Mat*_*hew 5 schema database-design sql-server referential-integrity
原谅我的标题,我想不出任何能准确描述我在说什么的东西。
我目前有以下关系。
CREATE TABLE Events
(
ID INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(64) NOT NULL,
PRIMARY KEY(ID)
)
CREATE TABLE Locations
(
ID INT IDENTITY(1,1) NOT NULL,
EventID INT NOT NULL,
Name NVARCHAR(64) NOT NULL,
PRIMARY KEY(ID)
)
ALTER TABLE Locations ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
Run Code Online (Sandbox Code Playgroud)
基本上,一个事件可以有零个或多个位置。我现在想要的是将捐赠与事件相关联,或者更具体地将其与位置相关联。
CREATE TABLE Donations
(
ID INT IDENTITY(1,1) NOT NULL,
EventID INT NOT NULL,
LocationID INT NULL, -- this is optional
PRIMARY KEY(ID)
)
ALTER TABLE Donations ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
ALTER TABLE Donations ADD FOREIGN KEY(LocationID) REFERENCES Locations(ID)
Run Code Online (Sandbox Code Playgroud)
但是,如果LocationID指定了 ,则它LocationID应该是属于指定的位置EventID。在LocationID指定的情况下,它会变得EventID多余,因此不再规范化。
是我提议考虑好形式架构,或者我应该使双方EventID和LocationID空,然后执行一个检查约束,要么完全EventID或LocationID应设置?
接下来,我们将进行注册。我提议的内容与此类似:
CREATE TABLE Users
(
ID INT IDENTITY(1,1) NOT NULL,
Username NVARCHAR(64) NOT NULL,
PRIMARY KEY(ID)
)
CREATE TABLE Registrations
(
UserID INT NOT NULL,
EventID INT NOT NULL,
LocationID INT NULL,
PRIMARY KEY(UserID, EventID)
)
ALTER TABLE Registrations ADD FOREIGN KEY(UserID) REFERENCES Users(ID)
ALTER TABLE Registrations ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
ALTER TABLE Registrations ADD FOREIGN KEY(LocationID) REFERENCES Locations(ID)
Run Code Online (Sandbox Code Playgroud)
本质上,用户可以注册一次事件(无论他们是否选择了位置)。如果我将主键EventID设为可空以防止使用EventID和进行数据冗余,那么我拥有的主键就会出现问题LocationID。
我们目前针对这个问题使用的解决方案是我们没有Locations桌子。
CREATE TABLE Events
(
ID INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(64) NOT NULL,
ParentEventID INT NULL, -- when null it's an event, otherwise it's a location for the eventid it references
PRIMARY KEY(ID)
)
ALTER TABLE Events ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
Run Code Online (Sandbox Code Playgroud)
它解决了EventID与LocationID数据冗余问题。但是我发现这种结构很奇怪,因为事件和位置在概念上是不同的。在未来,我们可能会有特定于事件和地点的字段。
要确定此Events表中的记录是事件还是位置,如果PrimaryEventID字段为NULL,则为事件,否则为该 的位置EventID。
请让我知道这些业务需求的良好架构。
代替:
ALTER TABLE Donations ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
ALTER TABLE Donations ADD FOREIGN KEY(LocationID) REFERENCES Locations(ID)
Run Code Online (Sandbox Code Playgroud)
我会这样做:
ALTER TABLE Donations ADD FOREIGN KEY(EventID) REFERENCES Events(ID)
ALTER TABLE Donations ADD FOREIGN KEY(EventID, LocationID) REFERENCES Locations(EventID, ID)
Run Code Online (Sandbox Code Playgroud)
这将保证“如果指定了 LocationID,则该 LocationID 应该是属于指定 EventID 的位置”。
完成后,您的方法就有意义了。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |