元查询的数据库结构

时间:2014-12-09 12:50:15

标签: database couchdb cloudant

我有一个具有以下结构的数据库:

+------+------+--------+-------+--------+-------+
| item | type | color  | speed | length | width |
+------+------+--------+-------+--------+-------+
|    1 |    1 |      3 |     1 |      2 |     2 |
|    2 |    1 |      5 |     3 |      1 |     1 |
|    3 |    1 |      6 |     3 |      1 |     1 |
|    4 |    2 |      2 |     1 |      3 |     1 |
|    5 |    2 |      2 |     2 |      2 |     1 |
|    6 |    2 |      4 |     2 |      3 |     1 |
|    7 |    2 |      5 |     1 |      1 |     2 |
|    8 |    3 |      1 |     2 |      2 |     2 |
|    9 |    4 |      4 |     3 |      1 |     2 |
|   10 |    4 |      6 |     3 |      3 |     2 |
+------+------+--------+-------+--------+-------+

我想有效地查询哪些字段组合有效。因此,例如,我想查询数据库以获取以下信息:

如果type为1,那么什么颜色值有效?

ans: [3, 5, 6]

如果类型为2且颜色为2,则什么速度值有效?

ans: [1, 2]

如果长度为2且宽度为2,则哪种类型的值有效?

ans: [1, 2]

SQL等价物是:

SELECT DISTINCT `color` FROM `cars` WHERE `type` =2
SELECT DISTINCT `speed` FROM `cars` WHERE `type` =2 AND `width` =2
SELECT DISTINCT `type` FROM `cars` WHERE `length` =2 AND `width` =2

我计划使用基于云的数据库(Cloudant DBAAS - 基于CouchDB)。如何最好地实现这一点,记住可能有数千个具有数十个字段的项目?

1 个答案:

答案 0 :(得分:0)

我没有过多考虑这个问题,因此方法中可能存在错误,但一个选项是用文档表示每一行:

{
  "_id": "1db91338150bfcfe5fcadbd98fe77d56",
  "_rev": "1-83daafc1596c2dabd4698742c2d8b0cf",
  "item": 1,
  "type": 1,
  "color": 3,
  "speed": 1,
  "length": 2,
  "width": 2
}

请注意,Cloudant为此示例自动生成了_id_rev字段。

然后,您可以在type字段上创建辅助索引:

function(doc) {
    if(doc.type)
        emit(doc.type);
}

使用type字段进行搜索:

https://accountname.cloudant.com/dashboard.html#database/so/_design/ddoc/_view/col_for_type?key=1&include_docs=true

typewidth字段的辅助索引:

function(doc) {
  if( doc.type && doc.width)
    emit([doc.type, doc.width]);
}

使用typewidth字段进行搜索:

https://accountname.cloudant.com/dashboard.html#database/so/_design/ddoc/_view/speed_for_type_and_width?key=[1,2]&include_docs=true

lengthwidth字段的辅助索引:

function(doc) {
    if (doc.length && doc.width)
        emit([doc.length, doc.width]);
}

使用lengthwidth字段进行搜索:

https://accountname.cloudant.com/dashboard.html#/database/so/_design/ddoc/_view/type_for_length_and_width?key=[2,2]&include_docs=true

完整的设计文档在这里:

{
  "_id": "_design\/ddoc",
  "_rev": "3-c87d7c3cd44dcef35a030e23c1c91711",
  "views": {
    "col_for_type": {
      "map": "function(doc) {\n    if(doc.type)\n        emit(doc.type);\n}"
    },
    "speed_for_type_and_width": {
      "map": "function(doc) {\n  if( doc.type && doc.width)\n    emit([doc.type, doc.width]);\n}"
    },
    "type_for_length_and_width": {
      "map": "function(doc) {\n    if (doc.length && doc.width)\n        emit([doc.length, doc.width]);\n}"
    }
  },
  "language": "javascript"
}