8

我想验证表中外键的正确处理。这是我在下面创建的两个表。一个人可能没有列出地址,所以我希望它为空。否则我想从地址表中引用一个主键并将其作为外键存储在 Person 表中。我们也可能有一个没有人的地址对象。

一个人的表:

CREATE TABLE Person
(
    PersonID int IDENTITY PRIMARY KEY,
    FName varchar(50) NULL,
    MI char(1) NULL,
    LName varchar(50) NULL,
    AddressID int FOREIGN KEY REFERENCES Address(AddressID) NULL,
)

地址表:

CREATE TABLE Address
(
    AddressID int IDENTITY PRIMARY KEY,
    Street varchar(60) NULL,
    City varchar(50) NULL,
    State varchar(2) NULL,
    Zip varchar(10)NULL,
    Intersection1 varchar(60) NULL,
    Intersection2 varchar(60) NULL,
)

另外 Q2 我从未使用过触发器,但我假设处理插入的方法是使用存储过程首先插入地址,获取主键,然后将其传递给存储过程以插入到 Person 表中?

4

2 回答 2

4

给你的问题:是否有可能不止一个人住在同一个地址?另外,一个人有可能住在多个地址上吗?

如果是这种情况,请考虑与附加 PersonAddress 表的 M:N 关系。

否则,如果不是这种情况,我会问自己“是否更有可能有没有地址的人或没有地址的人?” 目标是确定您是否应该将 AddressID 存储在 Person 表中,还是将 PersonID 存储在 Address 表中?

于 2013-04-12T08:43:12.993 回答
1

我会像这样更改地址:

 CREATE TABLE Address
 (
     AddressID int IDENTITY,
     Street varchar(60) NULL,
     City varchar(50) NULL,
     State varchar(2) NULL,
     Zip varchar(10)NULL,
     Intersection1 varchar(60) NULL,
     Intersection2 varchar(60) NULL,
 )
 Alter Table Address Add Constraint
 PK_Addresses Primary Key Clustered  
 (City Asc, Zip Asc, Street asc)

 Create Unique NonClustered Index IX_Address_Key
 On Address{AddressId)

我会这样做是因为,当您添加一个具有指定 StreetAddress、City 和 Zip 的人时,您可以在SavePerson存储过程中执行此操作。

If Exists (Select * From Address
           Where Street = @Street
              And City = @city
              And Zip = @zip)
   Begin
       Select @AddressId = AddressId
       From Address
       Where Street = @Street
           And City = @city
           And Zip = @zip
   End
Else Begin
      Insert Address(Street, City, State, Zip)
      Values(@street, @city, @state, @zip)
      Set @AddressId = Scope_Identity()
   End

然后使用插入到 Person 表中的 t-sql 变量 @AddressId 的值。您仍将使用 AddressId 来连接其他 SQL 语句,但您在城市、邮编和街道地址上有一个主键,这将防止您在地址表中插入重复的地址。将此设置为聚集索引,以防您可能需要检索或处理全部在一个 zip 中或全部在一个城市中的地址组......

于 2013-04-10T22:40:39.640 回答