草庐IT

mysql - 数据库设计——关系与属性

coder 2023-10-03 原文

我在设计数据库(SQL/MySQL)时遇到了问题。假设我们有一个用户,用户可以有很多 friend 和很多帖子,并填写了一些关于他自己的数据

很明显,对于friends,我们需要一个pivot_table 用于n:n 关系,对于posts,我们需要创建一个具有user_id (1:n) 关系的额外表.

所以我们需要usersuser_friendsposts 表。这是显而易见的。这才是处理关系的方式。

但现在假设我们希望用户拥有以下数据:

name - text
description - text
marital status - select only one from list
favourite colour - select only one from list
hobby - select up to 3 from list

对于文本字段(名称、描述),很明显我们只需在 users 表中创建 varchar/text 列即可。

一般问题是:应该如何处理其他字段(从列表中选择)?我应该为它们创建关系还是应该用它们创建标准数据列?

在我看来,没有必要为此创建关系表,因为使用列表(选择)我们只限制用户实际上可以粘贴到数据库中。理论上我们可以允许用户手动输入他喜欢的颜色作为他的颜色(例如 red 并且如果他输入错误的东西例如 reds 我们会比较它将会列出允许的 颜色)。性别也是如此——在我看来,当我们只容纳女人和男人并为其创建关系时,创建额外的表格是没有意义的。

第一个数据库设计:

例如,我可以为属性创建以下列:

marital_status - int
fav_colour - int
hobby_1 - int
hobby_2 - int
hobby_3 - int

还有另一个表(或者甚至是 PHP 或其他语言的普通数组),我在其中存储 fav_colour 的值 1 例如红色,爱好的值 2 是音乐等等(我如何存储并不重要这些值在这里 - 我也可以为此使用 enum 类型)。

对我来说,这种态度的好处不是创建许多实际上是属性而不是关系的关系(正如我上面提到的),因此工作量更少 + 更容易获取有关用户的信息 - 你不需要使用任何连接什么如果您有 20 或 100 个这样的属性,那将很重要,我可以很容易地在用户表中搜索。缺点也很明显 - 数据未标准化,对于任何多选(例如爱好)我需要创建 3 列,如果将来我决定用户不能选择 1 种颜色而是 2 或 3,我需要添加2 个额外的列。

替代数据库设计:

我创建了额外的表:colourshobbiesmarital_statuses 并且我创建了 3 个数据透视表:user_coloursuser_hobbiesuser_marital_statuses。缺点:许多连接。优点 - 如果我创建了 3 个额外的数据透视表,我可以轻松地允许用户选择多达 10 种颜色,而且我根本不需要重新设计数据库。但缺点也随之而来 - 搜索困难、工作量大、连接多。

详细问题

所以总结一下 - 假设哪种解决方案更好:

  1. 我可能不会更改一个属性的最大数量(如果我决定允许最多 3 个爱好,这可能永远不会改变)
  2. 许多字段的选择列表相对较短(大多数少于 10 个)
  3. 我需要在这样的数据库中进行大量搜索。例如,某人想要搜索将 fav_colour 设置为红色且有爱好音乐的用户。

如果您看到任何其他解决方案或优点/缺点,我很乐意与我分享。

最佳答案

听起来您想对您的某些用户属性实现一些约束。例如,最喜欢的颜色必须是红色、绿色、蓝色、粉色、橙色等之一;婚姻状况必须是单例、离婚、已婚之一。

您已经描述了一种方法:查找表。如果可能的值是动态的并且需要持续维护,或者如果有很多可能的值,这是最好的方法。从你的描述来看,那不是你的情况。您的可能值将是相当静态和简短的。

我建议使用 sql CHECK 约束。使用它,您可以控制字段的可能值。例如:

CREATE TABLE users
(
Name varchar(255) NOT NULL,
Description varchar(255),
Marital_Status varchar(10) NOT NULL,
Color varchar(10) NOT NULL,
CONSTRAINT chk_Color CHECK (Color in ('Red', 'Blue', 'Green', 'Orange')),
CONSTRAINT chk_Marriage CHECK (Marital_Status in ('Single', 'Married', 'Divorced'))
)

我没有对这个 DDL 语句进行语法检查,所以它可能包含标点符号错误。此外,语法可能因您的特定 DBMS 而异。我认为这应该适用于 MySQL。

关于mysql - 数据库设计——关系与属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26389176/

有关mysql - 数据库设计——关系与属性的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  7. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  8. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  9. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  10. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

随机推荐