【问题标题】:What are the pros and cons of the following database design?以下数据库设计的优缺点是什么?
【发布时间】:2010-09-04 23:00:57
【问题描述】:

我正在寻找有关以下设计的建议和评论。所有的表都应该是大表(数百万条记录),并且经常更新和查询,并且允许任何类型的更新(更新、插入、删除)。

-- product
create table Product(
productID int not null identity(1,1),
name varchar(100) not null,

constraint PK_Product primary key(productID)
)

-- client
create table Client(
clientID int not null identity(1,1),
name varchar(100) not null,

constraint PK_Client primary key(clientID)
)

-- order
create table [Order](
orderID int not null identity(1,1),
clientID int not null,
orderDateTime datetime not null,
orderAmount money not null,
orderNote varchar(max) null,

constraint PK_Order primary key(orderID),
constraint FK_Order_Client foreign key(clientID) references Client(clientID)
)

exec sp_tableoption 'Order', 'large value types out of row', 0

create index IX_Order_client on [Order](clientID)

-- items
create table OrderItem(
orderItemID int not null identity(1,1),
orderID int not null,
productID int not null,
qty int not null,
amount money not null,

constraint PK_OrderItem primary key(orderItemID),
constraint FK_OrderItem_Order foreign key(orderID) references [Order](orderID),
constraint FK_OrderItem_Product foreign key(productID) references Product(productID)
)

create index IX_OrderItem on OrderItem(orderID)

【问题讨论】:

  • 你需要做什么样的查询?
  • OrderItem在会计/发票中一般称为LineItem
  • 此假设设计用于 POS 系统 Mark。会有更新、插入、订单历史查询、AR 查询等
  • 按原样,一切都很好。我建议使用SUPPLIERS 表,以及将SUPPLIERS 链接到PRODUCTS 的多对多表——即使企业制造产品,产品也需要构建材料。因此,您可能需要从多个供应商处采购,并且/或者随着时间的推移,这些供应商会发生变化……
  • ...这意味着您需要 PRODUCTS 中的再订购点列在您的库存不足时进行标记,然后再进行延期销售。

标签: sql-server database tsql database-design relational-database


【解决方案1】:

这看起来不错。

您可能还希望对订单总费用的任何折扣或附加费用进行调整。目前还不清楚您打算如何处理您显示的订单金额 - 通常,订单总额可以从包含的部分的总和中计算出来。

此外,如果适用,请考虑一种用于指示订单将如何交付的发货方式,如果订单需要几个步骤来完成,还可以考虑一种状态。

【讨论】:

    【解决方案2】:

    1) 对于 OrderItem 表,我认为最好存储单价并 添加金额的计算字段:Amount AS Qty*UnitPrice [PERSISTED]。 此外,单价和金额字段的数据类型也很重要。你确定你需要4位小数吗?只使用 2 位小数不是更好吗(例如 NUMERIC(8,2))?

    2)此时,使用建议的设计,可以很容易地“复制”订单项目(订单ID和产品ID),因为OrderItem表没有任何限制:

    Order (1001, ...)
    OrderItem (1,1001,10,400,800),(2,1001,11,200,1200),(3,1001,10,400,800).
    

    解决方法是添加唯一索引:

    CREATE UNIQUE INDEX IUX_OrderItem_OrderID_ProductID 
    ON OrderItem (OrderID, ProductID)
    

    在某些情况下,OrderID + ProductID 可以重复,但 UnitPrice 会有所不同。 如果这是您的情况,那么唯一索引将有一个包含 3 个字段的键: 创建唯一索引 IUX_OrderItem_OrderID_ProductID_UnitPrice ON OrderItem(OrderID、ProductID、UnitPrice)

    3) 如果 SQL Server 版本 >= 2005,那么您可以为数据库对象使用模式。

    CREATE SCHEMA Sales;
    CREATE TABLE Sales.[Order] (...);
    CREATE TABLE Sales.OrderItem (...);
    

    4) 我的建议是不要无缘无故地创建索引 (IX_OrderItem):例如查询或限制。它们需要在每次 DML 操作时更新,并且需要存储空间。如果您想创建索引,请尽可能创建唯一索引。

    5) 我不明白为什么要将 VARCHAR(MAX) 数据类型用于 Order 表中的 orderNote 字段。 VARCHAR(8000) 或 NVARCHAR(4000) 还不够吗?您想为每个订单在该字段中插入一本小说吗?

    【讨论】:

      猜你喜欢
      • 2010-11-02
      • 2011-01-28
      • 2017-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      相关资源
      最近更新 更多