关系表设计问题

发布于 2024-10-13 02:55:34 字数 416 浏览 4 评论 0原文

如果行发生更改,如何保留历史关系数据?在此示例中,允许用户随时编辑属性表中的行。测试可以具有任意数量的属性。如果他们编辑“属性”表中的“名称”字段,或者在“属性”表中删除一行,则测试行可能不包含测试时的条件。您是否会通过添加属性名称列并删除 TestProperty 映射表来更改 Test 表的设计?属性名称列必须类似于分隔的字符串列表。问题通常如何处理?

3张桌子:

Test:
  TestId     AUTONUMBER, 
  Name       CHAR,
  TestDate   DATE

Property:
  PropertyId AUTONUMBER, 
  Name       CHAR

TestProperty:  (maps properties to tests)
  TestId
  PropertyId

How do you retain historical relational data if rows are changed? In this example, users are allowed to edit the rows in the Property table at any time. Tests can have any number of properties. If they edit the field 'Name' in the Property table, or drop a row in the Property table, Test rows might not hold conditions at the time of the test. Would you change the design of the Test table by adding a property names column, and dropping the TestProperty mapping table? The property names column would have to be something like a delimited list of strings. How is problem usually handled?

3 tables:

Test:
  TestId     AUTONUMBER, 
  Name       CHAR,
  TestDate   DATE

Property:
  PropertyId AUTONUMBER, 
  Name       CHAR

TestProperty:  (maps properties to tests)
  TestId
  PropertyId

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岛徒 2024-10-20 02:55:34

我认为这个问题还没有得到充分回答。

如果他们编辑属​​性表中的“名称”字段...您会通过添加属性名称列并删除 TestProperty 映射表来更改测试表的设计吗? p>

绝对不会。这会无缘无故地增加大量重复。

如果您的要求是在测试时保持数据值(在属性中)的完整性,则正确的(数据库)方法是实现历史表。这应该是源表的精确副本,加上一项:将 TIMESTAMP 或 DATETIME 列添加到 PK。

PropertyHistory
    PropertyId  AUTONUMBER,
    Name        CHAR
    CONSTRAINT  PRIMARY KEY CLUSTERED UC_PK (PropertyId)
PropertyHistory PropertyId INT, AuditedDtm DATETIME, Name CHAR CONSTRAINT PRIMARY KEY CLUSTERED UC_PK (PropertyId, AuditedDtm)

For this to be meaningful and useable, the Test table needs a timestamp as well, to identify which version of ProperyHistory to reference:

TestProperty
    TestId
    PropertyId
    TestDtm     DATETIME

属性名称列必须类似于分隔的字符串列表。

这会破坏基本设计规则以及数据库规范化规则,并阻止您对其执行普通的关系操作。切勿在单个列中存储多个数据值。

...或在属性表中拖放一行

删除又是不同的事情。如果它是一个“数据库”,那么它就具有完整性。因此,如果父行在其他表中具有子行,则无法删除该父行(如果它没有子行,则可以将其删除)。这通常被实现为“软删除”,添加诸如 IsObsolete 之类的指标。这在各种 SELECT 中引用以排除该行被使用(以添加新子项),但仍可用作现有子项的父项。

I do not think the question has been answered fully.

If they edit the field 'Name' in the Property table ... Would you change the design of the Test table by adding a property names column, and dropping the TestProperty mapping table?

Definitely not. That would add massive duplication for no purpose.

If your requirement is to maintain the integrity of the data values (in Property) at the time of the Test, the correct (database) method is to implement a History table. That should be an exact copy of the source table, plus one item: a TIMESTAMP or DATETIME column is added to the PK.

PropertyHistory
    PropertyId  AUTONUMBER,
    Name        CHAR
    CONSTRAINT  PRIMARY KEY CLUSTERED UC_PK (PropertyId)
PropertyHistory PropertyId INT, AuditedDtm DATETIME, Name CHAR CONSTRAINT PRIMARY KEY CLUSTERED UC_PK (PropertyId, AuditedDtm)

For this to be meaningful and useable, the Test table needs a timestamp as well, to identify which version of ProperyHistory to reference:

TestProperty
    TestId
    PropertyId
    TestDtm     DATETIME

The property names column would have to be something like a delimited list of strings.

That would break basic design rules as well as Database Normalisation rules, and prevent you from performing ordinary Relational operations on it. Never store more than one data value in a single column.

... or drop a row in the Property table

Deletion is something different again. If it is a "database" then it has Integrity. Therfore you cannot delete a parent row if it has child rows in some other table (and you can delete it if it does not have children). This is usually implemented as a "soft delete", an Indicator such as IsObsolete is added. This is referenced in the various SELECTS to exclude the row from being used (to add new children) but remains available as the parent for existing children.

在梵高的星空下 2024-10-20 02:55:34

如果你想保留财产关系,即使该财产不存在。使属性不一定被删除,但添加一个标志来指示该属性当前是否处于活动状态。如果属性的名称发生更改,请使用新名称创建新属性并将旧属性设置为非活动状态。

如果您这样做,则必须创建某种垃圾收集方式非活动属性。

我永远不会将单个列放入一个字段中,该字段模仿与逗号表示的列表的一对多关系。 否则,你就达不到关系数据库的目的。

If you want to retain property relations, even if the property doesn't exist. Make it so that Properties aren't necessarily deleted, but add a flag that denotes if the property is currently active. If a property's name is changed, create a new property with the new name and set the old property to inactive.

If you do this, you'll have to create some way of garbage collecting the inactive properties.

I'd never make a single column into a field that imitates a one-to-multi relationship with a comma-denoted list. Otherwise, you defeat the purpose of relational database.

少女净妖师 2024-10-20 02:55:34

似乎您正在使用 Test 作为测试特定实例的模板以及测试本身。也许每次用户根据 Test 中的规范执行测试时,都会在 TestRun 中创建一行?这将保留特定的 Property,并且如果 Property 中的条目稍后发生更改,则后续的 TestRun 将反映新的更改。

Seems like you're using Test as both a template for a particular instance of a test, as well as the test itself. Maybe every time a user performs a test according to the specification in Test, create a row in, say, TestRun? This would preserve the particular Propertys, and if the entries in Property change later, then subsequent TestRuns would reflect the new changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文