我有一个包含三个表的数据库,分别称为Sale
,Store
和Hub
。 Store
的每个实例都引用Hub
的实例,尽管在Hub
表中可能没有引用Store
的实例。在大多数情况下,Sale
的实例将引用Store
的实例(因此可以映射到Hub
的实例。)但是在某些情况下,Sale
将直接引用Hub
表。
此关系模型如下:商店由中心存储(商店和中心都是位置),并且大多数销售发生在商店中,但它们也可以在中心发生。
在不存在Sale
-Hub
关系的简化版本中,我可以轻松地使StoreID
成为Sale
表的主键的一部分,是我在这里想要做的,除了StoreID
偶尔会为空(当销售发生在中心而不是商店时)
因此,Sale
表中的示例可能如下所示:
SaleID SaleDate StoreID HubID Quantity
1 2012-05-16 1 NULL 100
2 2014-09-27 2 NULL 99
3 2018-02-01 NULL 9 30
4 2019-11-12 17 NULL 207
Store
和Hub
表将包括位置信息以及一些商店和中心特定字段。
问题是如何处理为Sale
表创建一个好的备用键(SaleID
是我的替代主键。)从理论上讲,应该根据日期和位置确定销售。但是我有两个位置字段,并且它们都是可为空的。我想知道是否可以使用唯一索引来处理此问题?还是可以以某种方式使用检查约束?还是中间位置表?
此外,作为后续操作,假设我还有一个SuperHub
表(想象Hub
是SuperHub
就是Store
是Hub
。)如果我想向SuperHubID
表中添加Sale
字段,这将如何影响事情?使用3个以上可为空的字段时,不检查约束/唯一索引是否开始失控?
这可能是ERD的样子:
编辑:为澄清起见,鉴于“位置信息”是在几个不同的表之间分割的,因此,我试图找出将位置信息作为Sale
表的备用键的一部分的最佳方法。 Sale
表的主键只是代理键SaleID
。)尝试将所有位置表包括在备用键中会导致Null出现在键中(请参阅Sale
中的示例表格。)解决此问题的最佳方法是什么?
编辑2:好的,这里还有一些澄清。我包括表格定义等。
--Table Defs
CREATE TABLE Sale (
SaleID int NOT NULL IDENTITY(1, 1),
SaleDate date NOT NULL,
StoreID int NULL,
HubID int NULL,
Quantity int NOT NULL);
-- StoreID and HubID are nullable since a sale can occur at one or the other
-- Is there a better way to organize this?
-- @PeterHe mentioned Category/Subcategory model
CREATE TABLE Store (
StoreID int NOT NULL IDENTITY(1, 1),
StoreNumber int NOT NULL,
Customer nvarchar(20) NOT NULL,
Address nvarchar(50) NOT NULL,
HubID int NOT NULL);
CREATE TABLE Hub (
HubID int NOT NULL IDENTITY(1, 1),
HubNumber int NOT NULL,
Customer nvarchar(20) NOT NULL,
Address nvarchar(50) NOT NULL);
--PKs
ALTER TABLE Sale
ADD CONSTRAINT PK_Sale PRIMARY KEY CLUSTERED (SaleID);
ALTER TABLE Store
ADD CONSTRAINT PK_Store PRIMARY KEY CLUSTERED (StoreID);
ALTER TABLE Hub
ADD CONSTRAINT PK_Hub PRIMARY KEY CLUSTERED (HubID);
--FKs
ALTER TABLE Sale
ADD CONSTRAINT FK_Sale_Store
FOREIGN KEY (StoreID) REFERENCES Store (StoreID)
ON UPDATE NO ACTION
ON DELETE NO ACTION;
ALTER TABLE Sale
ADD CONSTRAINT FK_Sale_Hub
FOREIGN KEY (HubID) REFERENCES Hub (HubID)
ON UPDATE NO ACTION
ON DELETE NO ACTION;
ALTER TABLE Store
ADD CONSTRAINT FK_Store_Hub
FOREIGN KEY (HubID) REFERENCES Hub (HubID)
ON UPDATE NO ACTION
ON DELETE NO ACTION;
--AKs
ALTER TABLE Store
ADD CONSTRAINT AK_Store UNIQUE (StoreNumber, Customer);
ALTER TABLE Hub
ADD CONSTRAINT AK_Hub UNIQUE (HubNumber, Customer);
ALTER TABLE Sale
ADD CONSTRAINT AK_Sale UNIQUE (SaleDate, StoreID, HubID);
--issue here is StoreID and HubID are nullable since sale could occur at either
答案 0 :(得分:1)
最好将一个实体定义为包括所有可以进行销售的组织,例如sale_org( sale_org_id int不为null, sale_org_type tinyint也不为null,-1,存储; 2,花鼓,3,超级花鼓 地址 ... ) 您仍然可以使用Store和Hub等表(无地址)来定义关系。或仅一个表用于层次结构sale_org_hierarchy定义关系:sale_org_id和parent_sale_org_id
销售表仅引用store_hierarchy表。