我有3个表:包,产品和服务:
create table dbo.Packages (
Id int identity not null
Name nvarchar (80) not null
)
create table dbo.Products (
Id int identity not null
Name nvarchar (80) not null
)
create table dbo.Services (
Id int identity not null
Name nvarchar (80) not null
)
我需要将3个表联系起来以满足以下要求:
由于(3)和(5),我不确定如何建立这个方案。
我可能需要Table继承,多对多关系和某种索引(5)?
有人可以就此提出建议吗?
更新
Frazz建议的一个选项是使用Component base table,如下所示,Service可以将ComponentId作为null。还有一个选择...
CREATE TABLE dbo.Packages (
id INT IDENTITY NOT NULL,
name NVARCHAR(80) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE dbo.Components (
id INT IDENTITY NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE dbo.Products (
id INT IDENTITY NOT NULL,
component_id INT NOT NULL,
name NVARCHAR(80) NOT NULL
PRIMARY KEY (id)
);
CREATE TABLE dbo.Services (
id INT IDENTITY NOT NULL,
component_id INT NULL,
name NVARCHAR(80) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE dbo.Package_Components (
package_id INT NOT NULL REFERENCES Packages(id),
component_id INT NOT NULL REFERENCES Components(id)
PRIMARY KEY (package_id, component_id)
);
答案 0 :(得分:2)
以下内容应解决您提出的大部分内容(在SQLFiddle上测试):
CREATE TABLE dbo.Packages (
id INT IDENTITY NOT NULL,
name NVARCHAR(80) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE dbo.Products (
id INT IDENTITY NOT NULL,
name NVARCHAR(80) NOT NULL
PRIMARY KEY (id)
);
CREATE TABLE dbo.Services (
id INT IDENTITY NOT NULL,
name NVARCHAR(80) NOT NULL,
can_be_packaged BIT NOT NULL
PRIMARY KEY (id)
);
CREATE TABLE dbo.Package_Products (
package_id INT NOT NULL REFERENCES Packages (id),
product_id INT NOT NULL REFERENCES Products (id)
PRIMARY KEY (package_id, product_id)
);
CREATE TABLE dbo.Package_Services (
package_id INT NOT NULL REFERENCES Packages (id),
service_id INT NOT NULL REFERENCES Services (id)
PRIMARY KEY (package_id, service_id)
);
另外两个表Package_Products和Package_Services实现了(1),(2)和(4)所需的多对多关系。他们的主键强制执行(5)。
剩下的是你的要求(3)。您说这完全取决于服务,因此额外的BIT列can_be_packaged是处理需求的好方法。但是你需要强制执行它。
问题是您无法在CHECK约束中执行SQL语句。所以我看到的唯一解决方案是在Package_Services表上有一个TRIGGER FOR INSERT和一个TRIGGER FOR UPDATE。这些触发器应该在Services表上执行SELECT并检查can_be_packaged位是否为。