因此,我需要使用状态字段设计产品生命周期的数据模型。状态可以说是:生产,服务,保修等。
经典方式只是具有单独的表状态,以及状态的外键。但是我想在这个专栏中只有字符串值。我理解的含义是:
主要好处是:
我错过了什么吗?我概述的含义是否真实?你的建议?
答案 0 :(得分:5)
我认为有一定数量的Status值,因此可以使用CHECK约束在DB中进行验证。外键约束几乎完全相同,但使用引用表中的值并锁定它们。
ALTER TABLE产品 添加约束CH_PRODUCTS_STATUS检查 ( 状态='生产'或状态='服务' ) GO
是。无论如何还要存储更多Int值将占用4个字节,而文本值“Services”将在varchar数据类型中占用8个字节,在nvarchar中占用16个字节。 Enterprise Edition中有一个页面压缩选项(在标准中也是自SQL Server 2016 SP1以来)https://msdn.microsoft.com/en-us/library/cc280464.aspx,正如您所见,据我了解这种压缩算法,int和varchar / nvarchar压缩之间的区别将是标题大小,因此如果Status值有一个小的有限选项,压缩将给你非常相同的结果。我创建了两个表(聚簇索引),它们具有相同的结构,但是对于Status列有不同的类型,并在每个表中插入100K行。
创建表产品 ( Id int IDENTITY PRIMARY KEY, Product varchar(200)NOT NULL, 状态varchar(50)NOT NULL, 日期datetime NOT NULL ) GO
创建表Products2 ( Id int IDENTITY PRIMARY KEY, Product varchar(200)NOT NULL, 状态int NOT NULL, 日期datetime NOT NULL ) GO
插入产品价值('5656','服务',GETDATE()) GO 100000
INSERT INTO Products2 VALUES('5656',1,GETDATE()) GO 100000
以下是他们的一些统计数据:
产品表格大小:543页(4.2 MB) 产品2工作台面积:482页(3.7 MB) 压缩产品(页面压缩)表格大小:173页 产品2压缩(页面压缩)表格大小:173页
注意:本演示中使用的varchar数据类型,nvarchar将需要比varchar多两倍的容量。
与上一个问题中的大小相同。以下是索引创建的脚本:
创建索引IX_PRODUCTS_STATUS ON产品(状态) GO
创建索引IX_PRODUCTS2_STATUS ON产品2(状态) GO
产品索引规模:260页 商品2索引尺寸:174页(3.7 MB) 产品索引(页面压缩)表大小:93页 产品2索引(页面压缩)表大小:93页
可用RAM可以很好地指示将状态存储在Products表中或将其移动到Statuses表,因为从RAM读取仍然比从磁盘读取快得多。可以使用状态列的值的长度来计算大小差异。如果大小差异很大且SQL Server无法在RAM中保存活动数据,他将从磁盘读取数据并从RAM中清除其他可能很重要的数据。在这种情况下,将状态值移动到单独的表或启用压缩(如果此选项可用)是有意义的。
但与此同时,如果您将拥有单独的Statuses表,那么从Products to Statuses表创建外键可能是有意义的。在这种情况下,通过查找Statuses表,数据修改操作会稍微缓慢。此外,您将有+1加入,并且物理连接操作的CPU开销很小(并且通常会被忽略)。
答案 1 :(得分:2)
不幸的是,此解决方案仅适用于您的应用程序的OLTP数据库存储。如果您需要使用该表进行聚合(报告,外部仪表板,日志记录和监视等)或与其他应用程序共享数据(ETL到DWH,复制到另一个DB,同步缩放节点等),您将面临几个严重的问题的问题:
有一天,您需要将数据从应用程序中分离出来,因为您的数据比遗留代码更有价值,因此最好事先做好准备。