楼主: jieforest

CouchDB中的Schemas详解

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2012-9-12 10:08 | 只看该作者
Nesting

You could have a nested object structure like:
  1. 01.{
  2. 02."datatype": "pattern/v1",
  3. 03."data": [
  4. 04.{
  5. 05."datatype": "triangle/v1",
  6. 06."data": [
  7. 07.879.07395066446952,
  8. 08.84.607510245708468,
  9. 09.1.4444230241122715,
  10. 10."red"
  11. 11.],
  12. 12."owner": "Simon",
  13. 13."location" "space"
  14. 14.},
  15. 15.{
  16. 16."datatype": "triangle/v1",
  17. 17."data": [
  18. 18.879.07395066446952,
  19. 19.84.607510245708468,
  20. 20.1.4444230241122715,
  21. 21."blue"
  22. 22.],
  23. 23."owner": "Fred",
  24. 24."location" "space"
  25. 25.},
  26. 26.{
  27. 27."datatype": "square/v1",
  28. 28.data: [
  29. 29.10,
  30. 30."green"
  31. 31.]
  32. 32.}
  33. 33.]
  34. 34.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2012-9-12 10:08 | 只看该作者
But if you're going to have a schema you may as well reflect the nesting inside it, e.g say that you have a list of triangles and a list of squares:
  1. 01.{
  2. 02."_id": "datatype/pattern/v1",
  3. 03."fields": [
  4. 04.["triangle/v1"],
  5. 05.["square/v1"]
  6. 06.]
  7. 07.}
  8. 08.
  9. 09.
  10. 10.{
  11. 11."datatype": "pattern/v1",
  12. 12."data": [
  13. 13.[
  14. 14.{
  15. 15."data": [
  16. 16.879.07395066446952,
  17. 17.84.607510245708468,
  18. 18.1.4444230241122715,
  19. 19."red"
  20. 20.],
  21. 21."owner": "Simon",
  22. 22."location" "space"
  23. 23.},
  24. 24.{
  25. 25."data": [
  26. 26.879.07395066446952,
  27. 27.84.607510245708468,
  28. 28.1.4444230241122715,
  29. 29."blue"
  30. 30.],
  31. 31."owner": "Fred",
  32. 32."location" "space"
  33. 33.}
  34. 34.],
  35. 35.[
  36. 36.{
  37. 37.data: [
  38. 38.10,
  39. 39."green"
  40. 40.]
  41. 41.}
  42. 42.]
  43. 43.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2012-9-12 10:08 | 只看该作者
Schema evolution

A nice feature of this way of working is that you can deal with schema evolutions; changing the format of your data.
  1. 01.{
  2. 02."_id": "datatype/triangle/v2",
  3. 03."fields": [
  4. 04."opposite_length_in_cm",
  5. 05."hypotenuse_length_in_cm",
  6. 06."angle_in_degrees",
  7. 07."colour_label"
  8. 08.]
  9. 09.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
14#
 楼主| 发表于 2012-9-12 10:09 | 只看该作者
There are only so many ways you can represent the data. While sometimes you may have a major schema evolution, one where old data is completely unusable, often changes are just tweaks for consistency (say changing the units of a quantity) or extending the schema by adding in optional data. In either case you should be able to use data from multiple schema versions together by using appropriate manipulations on the data. For example you could instantiate shape objects via a factory which knows how to create the right object for different schema versions.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
15#
 楼主| 发表于 2012-9-12 10:09 | 只看该作者
Validation

The above does no validation of the data; the color field in the input data could be set to a number instead of a string, the angle to something non- physical etc. If you really needed validation you could do it with CouchDB's validation functions.

If you go the fully validated route you'd want to define the schema in the design document (instead of as a normal doc) and use a CommonJS include to make sure that the validator in the app was doing the same thing as the schema. This ties you to a version of the design document (which is where the validators live), which may or may not be an issue. It will also considerably slow down insertion rate as CouchDB has to do more work to add your data.

Personally I prefer to put validation logic in the client making writes.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
16#
 楼主| 发表于 2012-9-13 12:57 | 只看该作者
Views

If I were using this way of working I would want to have a view which returned all the schema's defined on the database. This then allows me to build objects appropriately. A view to return schema's documents would look like:
  1. 1.function(doc) {
  2. 2.if (doc._id.slice(0, 'datatype'.length) == 'datatype') {
  3. 3.emit (doc._id.slice('datatype/'.length, doc._id.length), doc.fields)
  4. 4.}
  5. 5.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
17#
 楼主| 发表于 2012-9-13 12:57 | 只看该作者
You can pull out documents that have a schema with a simple view like:
  1. 1.function(doc) {
  2. 2.if (doc.datatype){
  3. 3.emit(doc.datatype, doc.data);
  4. 4.}
  5. 5.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
18#
 楼主| 发表于 2012-9-13 12:58 | 只看该作者
This can be queried to find objects of a given shape using CouchDB's view slicing

(e.g. ?startkey="square/v1"&endkey="square/v2") which returns data like:
  1. 1.{"id":"datatype/square/v1","key":["square/v1",0],"value":["side_length_in_mm","colour_label"]},
  2. 2.{"id":"f98ffe7e4cd91cbb0d904f9098499ca8","key":["square/v1",1],"value":[872.4342711412228,"green"]},
  3. 3.{"id":"f98ffe7e4cd91cbb0d904f909849a218","key":["square/v1",1],"value":[370.29971491443905,"yellow"]},
  4. 4.{"id":"f98ffe7e4cd91cbb0d904f909849acd0","key":["square/v1",1],"value":[8.799279300193753,"yellow"]}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
19#
 楼主| 发表于 2012-9-13 12:58 | 只看该作者
You'll notice the name of the "schema" is the key and the values are held in value.

This means I can parse the data into a set of appropriate objects with something like:
  1. 01.var objects = [];
  2. 02.
  3. 03.function build(schema, data){
  4. 04.// Build the appropriate object for the schema...
  5. 05.}
  6. 06.
  7. 07.for (row in data){
  8. 08.// build up the objects in a factory
  9. 09.var obj = build(row.key, row.value);
  10. 10.objects.push(obj);
  11. 11.}
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
20#
 楼主| 发表于 2012-9-13 12:58 | 只看该作者
If I wanted all versions of a shape the query would be, and used a vNUMERIC_COUNTER notation for versioning, ?startkey="square/v1"&endkey="square/vXXX" as numbers sort lower than strings.


Taking it to the extreme

If you are really worried about data size you can take this technique to the extreme by encoding the data arrays as a byte string and using the schema documents to describe that byte array. This effectively turns your JSON structure into something not dissimilar to a protocol buffer, at the expense of human readability and view complexity. If you are particularly concerned with data size over the wire (for example are writing an MMORPG) then this may be an acceptable trade off.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表