关于FriendFeed的MySql SchemaLess设计的问题

use*_*017 5 mysql nosql

Bret Taylor在这篇博文中讨论了SchemaLess Design:http://bret.appspot.com/entry/how-friendfeed-uses-mysql

看起来他们将不同类的对象存储到一个表中.然后构建更多的索引表.

我的问题是如何在一个类上构建索引.

例如,用户的博客是{id,userid,title,body}.用户的推文是{id,userid,tweet}.

如果我想为用户的博客构建索引,我该怎么办?

Bil*_*win 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: ... }'
);
Run Code Online (Sandbox Code Playgroud)

您还可以为每个逻辑类型的属性插入单独的索引表.使用您的示例,博客的用户标识与推文的用户标识不同.由于您刚刚插入了博客,因此您可以插入索引表中的博客属性:

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');
Run Code Online (Sandbox Code Playgroud)

不要插入任何推文索引表,因为你刚刚创建了一个博客,而不是一条推文.

您知道blog_userid参考博客中的所有行,因为这是您插入它们的方式.因此,您可以搜索给定用户的博客:

SELECT e.*
FROM blog_userid u JOIN entities e ON u.id = e.id
WHERE u.userid = 86765309;
Run Code Online (Sandbox Code Playgroud)

你的评论:

是的,您可以将实际列添加到实体表中,以查找适用于所有内容类型的任何属性.例如:

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
);
Run Code Online (Sandbox Code Playgroud)

entity_type和creation_date的列允许您按时间顺序(或反向时间顺序)爬行实体,并知道哪组索引表与给定行的实体类型匹配.