我正在为一个网站开发一个用户配置文件系统,并且正在思考什么是更好(可扩展)的方法。我想出了两个解决方案,我正在寻找任何输入或者指向我可能错过的东西。
以下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
# ...
);
显然,这根本不是很可扩展,并且添加了令人烦恼的其他属性。一个优点是我可以快速搜索匹配特定属性集的用户。我已经做了一些调查,这是一种非常常见的方法(例如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
);
使用此方法,每次使用都会有一组与之关联的键值对,这使得添加其他属性变得微不足道,以及在用户登录时加载用户配置文件。但是,我丢失了第一种方法中的所有类型信息(例如,DATETIME现在存储为格式化字符串),因此一些搜索变得烦人。这确实让我可以更好地控制选择用户想要公开显示的属性。
混合方法会更好地让我平衡两种方法的优点和缺点吗? SO使用什么方法?还有其他方法可以解决这个问题吗?
扩展名使用混合方法,将用户表中的属性插入user_profile表以控制其对其他用户的可见性或者可能被视为额外开销是否有利?
答案 0 :(得分:4)
我会使用混合方法。应该在用户表中添加一些基本属性,如用户名,电子邮件,lastlogindate等。次要重要项目可以作为键/值对添加。
通过这种方式,您仍然可以轻松搜索最重要的信息,并在不更改架构的情况下继续添加配置文件项。
答案 1 :(得分:3)
混合解决方案不是一个好的解决方案。基本上,您将其他属性存储到属性包表中。从长远来看,这将使报告和查询变得复杂。此外,将日期,整数,十进制,ntext等存储为varchar对于可伸缩性而言不是可接受的性能交换。如果需要,你会如何在该表之间建立关系?
更好的方法是拥有用户信息的用户表。然后,随着您的需求扩展,创建代表新功能的新类。这些新类可能会有相应的表。这样,当与用户关联的属性属于他们自己的空间时,您的“用户”类不会呈指数级扩展。是的,将来你可能真的有一个属于用户表的新属性。此时您需要返回并调整您的架构和DBAL,但这是易于理解的代码价格。
在您的示例中,您在第一个用户表中拥有该用户的地址信息。我做的一件事是我知道我不仅需要为用户存储地址。所以我将有一个单独的地址表,然后在User表中包含一个可以为空的AddressId。这样,当我有一个Stores表,一个Events表时,我也可以在那里包含AddressId关系。这种方法的副作用是,当我返回并向地址对象添加lat / long时,我的数据模型中的每个人都会获得这些新属性。
答案 2 :(得分:0)
出于性能和设计可扩展性的原因,我也会使用混合解决方案。
我倾向于认为像users
这样的表(我也喜欢表名上的复数)需要被分解成一个通常由其他对象操作的核心数据集,以及那些基本上只写的扩展位规范中的数据如“region”,“middleinitial”,“shoesize”可以转移到可扩展且不太频繁更新的区域。
答案 3 :(得分:0)
为什么不使用XML字段来存储非必要的附加信息。
这可以在配置文件中配置,你甚至可以更进一步,从配置中生成UI控件。