Kev*_*ney 7 database database-design entity-attribute-value
我正在为一个网站开发用户配置文件系统,并在思考什么是更好(可扩展)的方法.我想出了两个解决方案,我正在寻找任何输入或指向我可能错过的东西.
以下create table语句并不是可执行的,而只是用于了解所涉及的表的布局.
我最初的想法是这样的:
CREATE TABLE user(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_email VARCHAR(320),
user_joined DATATIME,
user_last_seen DATATIME,
user_name_first VARCHAR,
user_name_last VARCHAR,
user_name_alias VARCHAR,
user_location_country VARCHAR,
user_location_region VARCHAR,
user_location_city VARCHAR
# ...
);
Run Code Online (Sandbox Code Playgroud)
显然,这根本不是很可扩展,并且添加了令人讨厌的额外属性.一个优点是我可以快速搜索匹配特定属性集的用户.我已经做了一些环顾四周,这是一种非常常见的方法(例如Wordpress).
我的第二种方法(我正在玩的那种方法)更具可扩展性,但我对性能有点担心:
CREATE TABLE user(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_email VARCHAR(320)
);
CREATE TABLE user_profile(
user_id INT UNSIGNED NOT NULL,
visibility ENUM('PRIVATE', 'PUBLIC'),
name VARCHAR,
value VARCHAR
);
Run Code Online (Sandbox Code Playgroud)
使用此方法,每个用户都有一组与之关联的键值对,这使得添加其他属性变得微不足道,以及在用户登录时加载用户配置文件.但是我丢失了第一种方法中的所有类型信息(例如,DATETIME现在存储为格式化字符串),因此一些搜索变得烦人.这确实让我可以更好地控制用户想要公开显示哪些属性.
混合方法会更好地让我平衡两种方法的优缺点吗?SO使用什么方法?还有其他方法可以解决这个问题吗?
扩展:使用混合方法将来自用户表的属性插入user_profile表以控制其对其他用户的可见性或者可能被视为额外开销是否有利?
混合解决方案并不是一个好的解决方案。本质上,您将附加属性存储到属性包表中。从长远来看,这将使报告和查询变得复杂。此外,将日期、int、decimal、ntext 等存储为 varchar 不会是可扩展性的可接受的性能交换。如果需要的话,您将如何在该表之外建立关系?
更好的方法是有一个用户表来存储用户信息。然后,随着您的需求扩展,创建代表新功能的新类。这些新类可能会有相应的表。这样,当与用户关联的属性属于其自己的空间时,您的“用户”类不会呈指数级扩展。是的,将来您可能真的拥有属于用户表的新属性。那时,您需要返回并调整您的架构和 DBAL,但这就是易于理解的代码的代价。
在您的示例中,第一个用户表中有用户的地址信息。我做的一件事是我知道我不仅需要为用户存储地址。因此,我将有一个单独的地址表,然后在用户表中包含一个可为空的AddressId。这样,当我有一个 Stores 表、一个 Events 表时,我也可以在其中包含 AddressId 关系。该方法的副作用是,当我返回并将纬度/经度添加到地址对象时,我的数据模型中的每个人也都会获得这些新属性。