Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 多对多关系数据库的复合FK表_Php_Mysql_Sql_Database Design_Data Modeling - Fatal编程技术网

Php 多对多关系数据库的复合FK表

Php 多对多关系数据库的复合FK表,php,mysql,sql,database-design,data-modeling,Php,Mysql,Sql,Database Design,Data Modeling,我正在构建一个api,但我太害怕db设计会出错。我正在尝试使用一个地址簿,在这里员工可以有他们的地址(家、工作、其他)。那么这是多对多关系吗 我的数据库设计正确吗?将创建一个复合表以提高灵活性 删除和更新在这里重要吗?如何设置它以便删除一名员工,我们不想在其他两个表中保留其他记录?首先,我觉得有必要补充一点,这样做并不适合,我不确定,但如果有一个仅用于数据库的站点/板,我也不会感到惊讶。很多东西都是个人喜好和观点 也许像这样的地方更合适: 也就是说: 我会在表中将PK改为id,所以id就

我正在构建一个api,但我太害怕db设计会出错。我正在尝试使用一个地址簿,在这里员工可以有他们的地址(家、工作、其他)。那么这是多对多关系吗

我的数据库设计正确吗?将创建一个复合表以提高灵活性


删除和更新在这里重要吗?如何设置它以便删除一名员工,我们不想在其他两个表中保留其他记录?

首先,我觉得有必要补充一点,这样做并不适合,我不确定,但如果有一个仅用于数据库的站点/板,我也不会感到惊讶。很多东西都是个人喜好和观点

也许像这样的地方更合适:

也就是说:

  • 我会在表中将PK改为id,所以id就是id,person也是。做person.person\u id就变得多余了
  • id应该是
    INT(10)无符号自动递增
    10是十位,或大约999999999。你不能有负ID,所以DB应该强制执行。我做10是因为,它是
    INT(11)
    ,这样就保留了标志的位置。这并不是真的必要,但我这样做是出于对任何无符号int的习惯
  • 我会用复数形式表示桥接表
    人员\u地址
    。因为,
    person
    address
    中的记录是针对一个实体的。桥接表中的记录用于多个实体。对我来说,这让我更容易分辨出这是一张桥牌。其他的都是单数的,比如说复数
“命名约定”的主要内容是保持一致。如果你为你的id做了
{table}\u id
,那么就这样做吧。如果你做了
person
,不要做类似于表的
zipcodes
。即使是列名,如果你使用
person\u id
,那么就不要使用任何列,如
FullName
FullName
Full\u name
等。我想说的是,选择一种方法并坚持下去,如果你提前知道表名是单数的,那么编写代码时就容易多了。正如我所说,我喜欢桥牌的复数形式,因为你很少单独使用它们

为了这段关系。您仍然需要分别删除
个人
地址
。但是如果您将
个人地址中的记录更改为级联,则该记录将被更新或删除。我这样认为:定义关系的表就是接收更改的表

但这是应该的。假设您有两个地址相同的人员记录。如果删除一个人,则不希望同时删除他们的地址。此外,如果某人的地址被删除,您可能不希望此人被删除。因此,最多应该是:

person > persons_addresses > address
我不确定当桥接表中没有记录时是否有自动删除地址的方法。我一直都是手动完成的,但是如果没有更好的方法,可以使用
触发器来完成

供参考:

触发器是与表关联的命名数据库对象,当表发生特定事件时激活。

老实说,我从来没有这样做过,我认为触发器可能不会在级联操作上触发,我记得一些关于只在SQL语句上触发的事情。在这种情况下,最好只使用触发器从
person
执行删除操作。因此,您将删除一个人,触发器将触发,您将检查是否有其他人使用该地址,如果
false
您将同时删除
persons\u地址
记录和
地址
记录。如果
true
您只会删除
个人地址
记录


我要做的另一件事是将地址分解成一个单独的
zipcode
。在我的工作中,我们购买了一个包含所有美国Zipcode的DB表,其中包含所有城市、州、县、邮政编码(当然)以及纬度和经度

通过使用它,我们的地址表包含与zipcodes的多对一关系。一个zipcode可以有多个与之关联的地址。我们还使用状态表按状态对其进行分解。所以它变成了

address
 id | street | street2 | zipcode_id

zipcode
id | city | state_id | county | zip | latitude | longitude

state
 id | name | abbreviation 
然后,当用户输入zipcode时,它会显示一个自动完成,其中包含所有信息

然后,我们要做的最后一件事是规范化所有的
ST
N
NW
等。我们选择将它们更改为全名,以便
ST
在保存时变为
STREET
。我们这样做是因为你可以拥有像187北公园这样的街道地址,看起来像187北公园,比187北公园更糟糕。你会惊讶于地址的变化,我称之为“脏”或“脏”


所有这些加在一起,消除了许多错误。但正如我在评论中所说,我们处理的是诉讼数据,因此我们必须比仅仅是一个地址簿更准确、更复杂。

那么,在哪里问这样的问题呢?DB设计是自以为是的,但我认为发现一个糟糕的DB设计并不难。这取决于它有多难。数据库可能变得相当复杂。特别是如果你有循环关系。好的设计不仅仅是螺母和螺栓。它必须正确地建模数据。你不应该选择数据库模型,而应该选择数据。例如,我为诉讼做了一个数据库。现在的诉讼法规就像是
15 USC 20
然后
15 USC 20(a)
或者
15 USC 20(b)
,然后
15 USC 20(a)(1)
等等。本质上是一个树,所以我使用了嵌套集模型,这是一个真正的挑战,但这是正确的方法。看你不能有
15 USC 20(a)(