【问题标题】:How to design a SQL table where a field has many descriptions如何设计一个字段有很多描述的SQL表
【发布时间】:2017-08-08 14:12:04
【问题描述】:

我想创建一个产品表。本产品具有唯一的零件编号。但是,每个零件号都有不同数量的先前零件号,以及可以使用该零件的不同机器数量。

例如部件号:AA1007

的描述

以前的零件编号: AA1001、AA1002、AA1004、AA1005、...

机器品牌: Bosch、Indesit、Samsun、HotPoint、Sharp、...

机器品牌型号: Bosch A1, Bosch A2, Bosch A3, Indesit A1, Indesit A2,....

我想为此创建一个表,但我不确定如何进行。我能想到的是分别为以前的零件编号、机器品牌、机器品牌型号创建一个表格。

问题:设计这些表格的正确方法是什么?

【问题讨论】:

  • 您可能需要一大堆表格。您应该阅读 SQL 关系。多对一和多对多
  • 映射表...
  • PartSynonyms 表?当前零件编号在“零件”表中,其中 PartSynonyms 列出了主要零件 ID 以及该零件每个同义词的单独记录。
  • 我们真的需要了解如何使用、报告这些数据,如果您需要能够根据日期重新生成信息等。如果有多个,保持 Active from 和 active to date 可能会起作用零件可以同时处于活动状态;和一列表示替换为并显示替换该部分的父记录,允许您遍历层次结构以查找当前部分。 IMO 的未知数太多,无法提供高质量的答案。
  • @xQbert 我计划提取 3 个不同的报告(或网格视图)。 1-价格视图,2-历史价格视图 3-项目规格。但是,为了避免问一个广泛的问题,我没有将它们包括在我的问题中。我计划使用时间戳和日期时间来跟踪它们。

标签: sql


【解决方案1】:

当然有多种方式来设计表格。一个非常基本的方法是:

您可以创建如下表。我添加了ValidFromValidTill 列,以识别部件何时处于活动状态/正在使用中。 这取决于您的数据,如果数据类型 date 足够,或者您需要 datetime 使其更准确。

CREATE TABLE Parts
(
      ID            bigint NOT NULL
     ,PartNo        varchar(100)
     ,PartName      varchar(100)
     ,ValidFrom     date
     ,ValidTill     date
)

CREATE TABLE Brands
(
      ID            bigint NOT NULL
     ,Brand         varchar(100) 
)

CREATE TABLE Models
(
      ID            bigint NOT NULL
     ,BrandsID      bigint NOT NULL
     ,ModelName     varchar(100) 
)


CREATE TABLE ModelParts
(
      ModelsID      bigint NOT NULL 
     ,PartID        bigint NOT NULL
)

填写您的数据,如:

INSERT INTO Parts VALUES 
(1,'AA1007', 'Screw HyperFuturistic',   '2017-08-09', '9999-12-31'),
(1,'AA1001', 'Screw Iron',              '1800-01-01', '1918-06-30'),
(1,'AA1002', 'Screw Steel',             '1918-07-01', '1945-05-08'),
(1,'AA1004', 'Screw Titanium',          '1945-05-09', '1983-10-05'),
(1,'AA1005', 'Screw Futurium',          '1983-10-06', '2017-08-08')


INSERT INTO Brands VALUES 
(1,'Bosch'),
(2,'Indesit'),
(3,'Samsung'),
(4,'HotPoint'),
(5,'Sharp')


INSERT INTO Models VALUES 
(1,1,'A1'),
(2,1,'A2'),
(3,1,'A3'),
(4,2,'A1'),
(5,2,'A2')

INSERT INTO ModelParts VALUES 
(1,1)

选择“Bosch A1”的某个日期(在本例中为 2013-03-03)的所有部分:

DECLARE @ReportingDate date = '2013-03-03'

         SELECT B.Brand
               ,M.ModelName
               ,P.PartNo
               ,P.PartName
               ,P.ValidFrom
               ,P.ValidTill
           FROM Brands B
     INNER JOIN Models M
             ON M.BrandsID  = B.ID
     INNER JOIN ModelParts MP
             ON MP.ModelsID = M.ID
     INNER JOIN Parts P
             ON P.ID = MP.PartID         
          WHERE B.Brand          = 'Bosch'
            AND M.ModelName      = 'A1'
            AND P.ValidFrom     <= @ReportingDate
            AND P.ValidTill     >= @ReportingDate       

当然,有多种方法可以对数据进行历史记录。 ValidFrom 和 ValidTill (ValidTo) 是我的最爱之一,因为您可以轻松地进行历史报告。 不幸的是,您必须处理历史记录:插入新行时 - 例如对于您的螺丝 - 您必须通过在插入新记录之前设置 ValidTill 列来“关闭”旧记录。此外,您必须开发逻辑来处理删除...

嗯,这是一个相当大的话题。您会在万维网上找到大量信息。

【讨论】:

  • 谢谢。这就是我的想法。感谢您澄清事情。但是,零件编号对我来说并不清楚。请注意,它们都是相同的部件(例如它们都是相同的螺钉),但部件编号已及时更改。所以我需要跟踪这些零件编号。 @Tim Biegeleisen 提供的解决方案很有意义,但我不知道如何添加新的先前零件号。在这种情况下,我之前添加的部件号将是最新的。您是否有其他解决方案来跟踪这一点?
  • @HappyForever 我刚刚更新了我的帖子。我删除了 Partent/Child 逻辑并在 Parts 表中添加了一个时间段。这可能就是您一直在寻找的内容
  • 是的,这就是我要找的。我不确定使用这么多带有 2 个字段的表是否是一个好习惯,现在我知道这是一个好习惯。但是,当有这么多表时,我不确定如何更新所有连接的字段。我想我会问这个问题。
【解决方案2】:

对于零件编号表,您可以考虑以下建议:

id | part_no | time_created
1  | AA1007  | 2017-08-08
1  | AA1001  | 2017-07-01
1  | AA1002  | 2017-06-10
1  | AA1004  | 2017-03-15
1  | AA1005  | 2017-01-30

换句话说,您可以添加一个datetime 列,用于对每个部件号进行版本控制。请注意,我在这里添加了一个主键 id 列,它随着时间的推移是不变的,并且会跟踪每个部分,尽管部件号可能会发生变化。

对于与时间无关的查询,您可以使用id 列连接此表。但是,部件号也可以用作外键。在我的脑海中,如果您是从前一个日期生成发票,您可能会在那时查找适当的部件号,然后使用该部件号连接到一个或多个表。

对于你提到的其他表,我没有看到类似的要求。

【讨论】:

  • 6 小时 6 分 5 秒。再过一秒钟,您将进入地狱般的时间。可行的答案。我喜欢它来管理部分过时并且仍然有以前的数据;但如果它不是一个过时的活动,那么我们可能需要一个具有父子层次结构或同义词的子表,但这适用于某些用例。
  • 感谢您的回答。这对于之前的零件编号表来说是一个很好的解决方案。但是,时间戳是自动创建的。那么如果我想调整之前的零件编号,即添加另一个,更改当前的零件号怎么办?
  • 我没有想到以前的零件表,只有一个包含当前和以前的所有零件号的表。您始终可以识别当前的表,因此您甚至可能不需要单独的表来存放以前的表。随意添加和删除(如果您有其他要求,此评论可能会更改)。
  • @Tim Biegeleisen 感谢您的评论。跟踪以前的零件编号的正确方法是什么?有时一个零件没有以前的零件编号,有时有2个,有时有9个,所以会有所不同。并且每当有替换零件(新零件)时,当前零件编号将是以前的零件编号。
  • @TimBiegeleisen 这就是我的意思:stackoverflow.com/questions/4592658/…。我无法更改时间戳,每当我插入或更新时,时间戳都会自动更新。你的意思是日期时间而不是时间戳?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
相关资源
最近更新 更多