简体   繁体   English

SQL模式设计和规范化

[英]SQL schema design and normalization

I've designed tables for my projects a few different ways and I'm curious to have peoples opinion if they feel one is more correct. 我已经以几种不同的方式为我的项目设计了表格,并且我很想问一下人们是否认为一种方法更正确,以征询他们的意见。

The example will involve Users,Stores,Addresses, and Phone Numbers. 该示例将涉及用户,商店,地址和电话号码。

Example A 例子A

  • user table - contains all main user data 用户表-包含所有主要用户数据
  • user address table - contains all address data 用户地址表-包含所有地址数据
  • user phone number table - contains all phone number data 用户电话号码表-包含所有电话号码数据
  • store tables mimic the above standard 存储表模仿以上标准

Saving 保存

once a parent entity is saved, everything else can be batch inserted/updated 保存父实体后,即可批量插入/更新其他所有内容

Example B - address table - contains all address data - phone number table - contains all phone number data 示例B-地址表-包含所有地址数据-电话号码表-包含所有电话号码数据

  • user table - contains all main user data 用户表-包含所有主要用户数据
  • user address table - is a linking table to the address table 用户地址表-是地址表的链接表
  • user phone number table - is a linking table to the phone number table 用户电话号码表-是到电话号码表的链接表
  • store table - mirrors the above standard 储物桌-符合上述标准

Saving 保存

I would start a transaction and loop through all addresses saving them one by one. 我将开始一个事务并遍历所有地址,一一保存。 Getting the last insert id and link them to the respective foreign entity. 获取最后一个插入ID,并将其链接到相应的外部实体。

This method forces the use of active record from what I can see and has no solution for doing batch insert/updates but greatly decreases the amount of "main" tables that in the database 从我所看到的方法中,该方法将强制使用活动记录,并且没有解决方案来进行批量插入/更新,但是大大减少了数据库中“主”表的数量

Thoughts 思想

As more time goes on I'm starting to believe example B is incorrect. 随着时间的流逝,我开始相信示例B是不正确的。 Normalization is about not duplicating data for their respected entity, not duplicating storage areas for your entire database. 规范化是关于不为其受尊敬的实体复制数据,而不是为整个数据库复制存储区域。

Anyways all thoughts/opinions are greatly appreciated. 无论如何,所有想法/意见都将不胜感激。 Thanks! 谢谢!

Additional thoughts 其他想法

So I've been thinking about this some more and here are my thoughts 所以我一直在考虑这个,这是我的想法

A user and store in this example would fall into the category of an aggregate root in DDD. 在此示例中,用户和商店将属于DDD中的聚合根类别。 This says that any child object should not be able to exist without the parent. 这说明没有父对象就不能存在任何子对象。

In example A if you delete a user or store there would be no way to have it deleted by foreign key, which I think screams that it breaks the aggregate root rule. 在示例A中,如果您删除用户或存储,则无法通过外键删除它,我认为这是违反了汇总根规则的。

Even though phone numbers and addresses have unique id's within the database and may even have those id's referenced at times through out the db they are still in fact value objects. 即使电话号码和地址在数据库中具有唯一的ID,甚至有时在数据库中有时也引用了这些ID,但它们实际上仍是有价值的对象。 Users and stores would be the real entities in this situation having value objects of phone numbers and addresses ( even though they have an id ) 在这种情况下,用户和商店将是真正的实体,具有电话号码和地址的值对象(即使它们具有id)

I was also confused in Example A how to load things using the repository pattern without having repositories talk to each other. 在示例A中,我也很困惑如何使用存储库模式加载内容而不使存储库互相交谈。 Which this new line of thinking also resolves. 这种新思路也可以解决。

I would suggest do the following. 我建议执行以下操作。 Create a table where duplicates or multiple records are not required. 创建一个不需要重复或多个记录的表。

Users : All user data including phone no,addresses ets Condition : The above should be applied when each user has a single phone number and single address. 用户:包括电话号码,地址和地址在内的所有用户数据条件:当每个用户具有一个电话号码和一个地址时,应采用上述方法。

The above could be used but for multiple phone no, and addresses you will have to use comma seperated field. 可以使用上面的方法,但是对于多个电话号码,您必须使用逗号分隔的字段作为地址。 To search in Comma seperated fields you will have to use FIND_IN_SET. 要在逗号分隔的字段中进行搜索,您必须使用FIND_IN_SET。

Users : All user data excluding phone and address 用户:所有用户数据,不包括电话和地址
Phone : linked with users with foreign ket 电话:通过国外ket与用户链接
Address : Linked with users with foreign key 地址:通过外键与用户链接
In this Method you will have to use joins 在此方法中,您将必须使用联接
And for insert and update you will need to use loop. 对于插入和更新,您将需要使用循环。

Recommendation 建议
I would say use first method . 我会说使用第一种方法。 And use second method when you really need it for example a user has many posts so create a table posts because there posts can be too many not a limited no but in the case of addresses and phone no they could be limited. 并在您确实需要时使用第二种方法,例如,一个用户有很多帖子,因此创建一个表格帖子,因为那里的帖子可能太多而不是没有限制,但在地址和电话号码的情况下可能会受到限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM