我有一个数据库,可以存储一些用户。每个用户都有自己的帐户设置,隐私设置和许多其他要设置的属性。这些房产的数量开始增长,最终可能会有30个房产。
到目前为止,我曾经将它保存在“UserInfo”表中,其中User和UserInfo与One-To-Many相关(保留所有更改的日志)。将它放在一个“UserInfo”表中听起来不太好,至少在数据库模型中,它看起来会很混乱。解决方案是什么?
在单独的表中分离隐私设置,帐户设置和其他“组”设置,并且在UserInfo和每组设置表之间具有1-1关系是一种解决方案,但在检索时会太慢(或者更慢)数据?我想所有数据都不会在同一时刻出现在一个页面上。所以也许每个表的一对多关系也是一个解决方案(分别保留每个组的日志)?
答案 0 :(得分:1)
如果它只有30个属性,我建议只创建30列。对于现代数据库而言,这并不算太多。
但是我想如果你现在拥有30个属性,随着时间的推移,你将继续发明新的属性,并且列数将继续增长。重新构建表以每天添加列可能会变得非常耗时,因为您会获得大量行。
有关替代解决方案,请查看此博客,了解以“无模式”方式存储大量动态属性的漂亮解决方案:How FriendFeed Uses MySQL。
基本上,将所有属性收集为某种格式并将其存储在单个TEXT列中。格式是半结构化的,即您的应用程序可以根据需要分离属性,但您也可以随时添加更多,甚至每行都有不同的属性。 XML或YAML或JSON是示例格式,或者是应用程序代码语言支持的某种对象序列化格式。
CREATE TABLE Users (
user_id SERIAL PRIMARY KEY,
user_proerties TEXT
);
这使得在给定属性中搜索给定值变得困难。因此,除了TEXT列之外,还要为要搜索的每个属性创建一个辅助表,其中包含两列:给定属性的值,以及返回主表的外键,其中找到该特定值。现在您可以索引列,以便快速查找。
CREATE TABLE UserBirthdate (
user_id BIGINT UNSIGNED PRIMARY KEY,
birthdate DATE NOT NULL,
FOREIGN KEY (user_id) REFERENCES Users(user_id),
KEY (birthdate)
);
SELECT u.* FROM Users AS u INNER JOIN UserBirthdate b USING (user_id)
WHERE b.birthdate = '2001-01-01';
这意味着当您在用户中插入或更新行时,还需要插入或更新每个辅助表,以使其与您的数据保持同步。当您添加更多辅助表时,这可能会变成一项复杂的工作。