我有一个具有以下结构的数据库:
+------+------+--------+-------+--------+-------+
| 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 |
+------+------+--------+-------+--------+-------+
我想高效地查询哪些字段组合是有效的。因此,例如,我想在数据库中查询以下内容:
如果类型为 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)。记住可能有数千个项目和数十个字段,这将如何最好地实现?
最佳答案
我没有对这个问题考虑太多,所以方法可能有错误,但一个选择是用文档表示每一行:
{
"_id": "1db91338150bfcfe5fcadbd98fe77d56",
"_rev": "1-83daafc1596c2dabd4698742c2d8b0cf",
"item": 1,
"type": 1,
"color": 3,
"speed": 1,
"length": 2,
"width": 2
}
请注意,_id
和 _rev
字段已由 Cloudant 为此示例自动生成。
然后您可以在 type
字段上创建二级索引:
function(doc) {
if(doc.type)
emit(doc.type);
}
使用 type
字段进行搜索:
type
和 width
字段的二级索引:
function(doc) {
if( doc.type && doc.width)
emit([doc.type, doc.width]);
}
使用 type
和 width
字段进行搜索:
length
和 width
字段的二级索引:
function(doc) {
if (doc.length && doc.width)
emit([doc.length, doc.width]);
}
要使用 length
和 width
字段进行搜索:
完整的设计文档在这里:
{
"_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"
}
关于元查询的数据库结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27379377/