Bret Taylor在这篇博文中讨论了SchemaLess Design:http://bret.appspot.com/entry/how-friendfeed-uses-mysql
看起来他们只将不同类的对象存储到一个表中。然后构建更多的索引表。
我的问题是如何在一个类上构建索引。
例如,用户的博客是{id,userid,title,body}。用户的推文是{id,userid,tweet}。
如果我想为用户的博客构建索引,我该怎么办?
答案 0 :(得分:10)
这很简单 - 也许比你预期的要简单。
当您存储博客实体时,您当然会插入主实体表。博客是这样的:
CREATE TABLE entities (
id INT AUTO_INCREMENT PRIMARY KEY,
entity_json TEXT NOT NULL
);
INSERT INTO entities (id, entity_json) VALUES (DEFAULT,
'{userid: 8675309,
post_date: "2010-07-27",
title: "MySQL is NoSQL",
body: ... }'
);
您还可以为每个逻辑类型的属性插入单独的索引表。使用您的示例,博客的用户标识与推文的用户标识不同。由于您刚刚插入了博客,因此您可以插入索引表中的博客属性:
CREATE TABLE blog_userid (
id INT NOT NULL PRIMARY KEY,
userid BIGINT UNSIGNED,
KEY (userid, id)
);
INSERT INTO blog_userid (id, userid) VALUES (LAST_INSERT_ID(), 8675309);
CREATE TABLE blog_date (
id INT NOT NULL PRIMARY KEY,
post_date DATETIME UNSIGNED,
KEY (post_date, id)
);
INSERT INTO blog_date (id, post_date) VALUES (LAST_INSERT_ID(), '2010-07-27');
不要插入任何推文索引表,因为你刚刚创建了博客,而不是推文。
您知道blog_userid
参考博客中的所有行,因为这是您插入博客的方式。因此,您可以搜索给定用户的博客:
SELECT e.*
FROM blog_userid u JOIN entities e ON u.id = e.id
WHERE u.userid = 86765309;
重新评论:
是的,您可以将实际列添加到实体表中,以查找适用于所有内容类型的任何属性。例如:
CREATE TABLE entities (
id INT AUTO_INCREMENT PRIMARY KEY,
entity_type INT NOT NULL,
creation_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
entity_json TEXT NOT NULL
);
entity_type和creation_date的列允许您按时间顺序(或按时间顺序倒序)抓取实体,并知道哪组索引表与给定行的实体类型匹配。
答案 1 :(得分:0)
它们不会在同一个表中存储不同类的对象。他们所指的“实体”表仅用于存储一种实体。
例如,FriendFeed中的典型实体可能如下所示:
"id": "71f0c4d2291844cca2df6f486e96e37c",
"user_id": "f48b0440ca0c4f66991c4d5f6a078eaf",
"feed_id": "f48b0440ca0c4f66991c4d5f6a078eaf",
"title": "We just launched a new backend system for FriendFeed!",
"link": "http://friendfeed.com/e/71f0c4d2-2918-44cc-a2df-6f486e96e37c",
"published": 1235697046,
"updated": 1235697046,
要更好地理解实现,请查看此处给出的示例:https://github.com/jamesgolick/friendly#readme