我正在构建一个api,但我对db设计太害怕了。我正在尝试练习一本地址簿,员工可以在那里找到他们的地址(家庭,工作,其他)。那么多对多的关系呢?
我的数据库设计是否正确?为了灵活性而创建复合表
ON DELETE和ON UPDATE在这里很重要吗?如何设置它以便删除员工,我们不想在其他2个表中保留其他记录?
答案 0 :(得分:1)
首先,我觉得有必要补充说,SO并不是真正适合这个的地方,我不确定,但如果有一个仅适用于数据库的网站/电路板,我不会感到惊讶。很多这样的东西都是个人偏好和意见。
可能这样的事情会更合适:
https://dba.stackexchange.com/
那说:
id
,所以address_type.id
它只是id而且对于人来说是相同的。做person.person_id INT(10) unsigned AUTO INCREMENT
10是十位,或大约99,999,999,999。您不能拥有否定ID,因此数据库应该强制执行此操作。我做了10,因为它是INT(11)
并且保留了标志位。它不是真的有必要,但我是出于习惯对任何unsigned int。persons_addresses
。因为,person
或address
中的记录适用于一个实体。桥表中的记录适用于多个实体。对我而言,它更容易让人知道它是一个桥牌桌。例如,所有其他都是单数,这些是复数。"命名约定的主要内容"要保持一致。如果你为你的身份{table}_id
做了,那么就这样做。如果person
zipcodes
没有为表格做person_id
。甚至列名如果你FullName
,那么就不要做fullName
,Full_name
或person
等任何列。我会说选择一种方法并坚持下去,它如果您提前知道表名是单数的,那么在编写代码时会更容易。正如我所说,我喜欢桥牌表的多次使用,因为你很少自己使用它们。
关系。您仍然需要单独删除address
和persons_addresses
。但如果您将其更改为级联,则person > persons_addresses > address
中的记录将被更新或删除。我这样想:定义关系的表是接收变化的表。
这是应该的方式。想象一下,你有2个人的记录具有相同的地址。如果您删除了一个人,则不希望从这两个人中删除该地址。此外,如果他们的地址被删除,您可能不希望删除某个人。所以最多应该是:
trigger
我不确定当桥表中没有记录时是否有自动删除地址的方法。我总是手动完成它,但如果没有更好的方法,你可以使用person
来做。
供参考:
触发器是与表关联的命名数据库对象,并在表发生特定事件时激活。 https://dev.mysql.com/doc/refman/5.7/en/triggers.html
说实话,我从来没有为此做过,我认为触发器可能不会触发级联操作,我记得有些事情只是被解雇了SQL语句。在这种情况下,最好只使用触发器从false
进行删除。因此,您将删除一个人,触发器将触发,您将检查是否有其他人使用该地址,如果persons_addresses
您同时删除了address
记录和true
记录。如果persons_addresses
您只会删除zipcode
记录。
我要做的另一件事是,将地址分解为单独的address
id | street | street2 | zipcode_id
zipcode
id | city | state_id | county | zip | latitude | longitude
state
id | name | abbreviation
。在我的工作中,我们购买了一个包含所有美国邮政编码的数据库表,其中包含所有城市,州,县,邮政编码(当然)以及纬度和经度。
通过使用我们的地址表包含与zipcodes的多对一关系。一个邮政编码可以有许多与之关联的地址。我们还使用状态表通过状态将其打破。所以它变成
ST
然后,当用户输入一个邮政编码时,它会显示一个包含所有信息的自动填写。
然后,我们要做的最后一件事是规范化所有N
,NW
,ST
等。我们选择将它们更改为全名,以便STREET
成为{{ 1}}保存时我们采用了这种方式,因为您可以使用187 NORTH PARK
这样的街道地址,看起来像187 N PARK
,这会比187 PARK NE
成为187 PARK NORTH EAST
更糟糕。你会惊讶于地址的变化,我称之为"污垢"或"肮脏"。
所有这些结合起来,消除了很多错误。但正如我在评论中所说,我们处理的是诉讼数据,因此我们必须具有更高的准确性,因此更加复杂,而不仅仅是一本地址簿。