AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 36698
Accepted
kevinskio
kevinskio
Asked: 2013-03-15 06:10:13 +0800 CST2013-03-15 06:10:13 +0800 CST 2013-03-15 06:10:13 +0800 CST

使用递归表强制数据完整性

  • 772

我有一个适用于 Web 应用程序的现有 oracle 11g 数据库模式。我正计划对应用程序进行扩展,以便 Web 服务可以对数据库进行数据操作。作为计划的一部分,我已经意识到没有对父/子关系的数据完整性检查,这会使其他应用程序使用该表成为问题。我计划在 Web 服务中进行验证,但最佳做法是在数据库和 Web 服务中进行验证。

--the base lookup table has a table with text values that is not shown.
--Example Red, Green, 
CREATE TABLE PROPERTY
(
  ID                        NUMBER(9)           NOT NULL, --PRIMARY KEY
  TENANT_ID                 NUMBER(9)           NOT NULL
)
-- a property may or may not have a parent property. 
--Example "Weight" of an item is a child of the "Shipping Weight"
CREATE TABLE PROPERTY_DEPENDENCY  --PRIMARY KEY PROPERTY_ID,PROPERTY_TYPE_ID
(
  PROPERTY_ID               NUMBER(9)           NOT NULL,
  PARENT_PROPERTY_ID        NUMBER(9),
  PROPERTY_TYPE_ID          NUMBER(9)           NOT NULL,
  ACTIVE                    NUMBER(1)           NOT NULL
)
--examples "Item Colour", "Item Trim Colour","Shipping Weight", "Weight"
CREATE TABLE PROPERTY_TYPE
(
  ID                        NUMBER(9)           NOT NULL,  --PRIMARY KEY
  VALUE                     VARCHAR2(200 BYTE)  NOT NULL,
  PROPERTY_TYPE             NUMBER(10)          DEFAULT 1   NOT NULL
)

--and the table that you insert and update into
CREATE TABLE CASE_PROPERTY
(
  ID                        NUMBER(9)           NOT NULL, --PRIMARY KEY
  PARENT_ID                 NUMBER(9),          --constraint on PROPERTY
  CASE_ID                   NUMBER(9)           NOT NULL,--foreign key
  PROPERTY_ID               NUMBER(9),          --constraint on PROPERTY
  PROPERTY_TYPE_ID          NUMBER(9)           NOT NULL --constraint on PROPERTY_TYPE
)

这些是我发现的问题:

  • 您可以插入到 CASE_PROPERTY 中并使属性成为自己的父母或祖父母
  • 您可以将 PROPERTY_ID 的错误 PROPERTY_TYPE_ID 插入 CASE_PROPERTY
  • 您可以在 CASE_PROPERTY 中插入一个 PARENT_ID,这对 PROPERTY_TYPE_ID 没有意义

我可以添加一个检查约束,PARENT_ID <> PROPERTY_ID这样你就不能成为自己的父母。

编辑 3: 真正的问题是表格没有正确规范化,这对报告非常有用,但很难进行数据验证。CASE_PROPERTY.PROPERTY_TYPE_ID应该始终与中的值相同,PROPERTY_DEPENDENCY.PROPERTY_TYPE_ID但我不知道如何验证这一点。

除了触发器之外,还有其他方法可以强制执行数据完整性CASE_PROPERTY吗?

编辑:我会整理一个完整的例子。如果我在上添加外键约束,PROPERTY_DEPENDENCY我将验证是否只插入了具有父项的属性,但它们是正确的父项吗?

编辑 2:这是允许插入的完整示例。最后两个插入是允许但不应插入的数据示例。

ALTER TABLE CASE_PROPERTY ADD  CONSTRAINT CASE_PROPERTY_R01  FOREIGN
KEY (PARENT_ID)  REFERENCES CASE_PROPERTY (ID)  ENABLE  VALIDATE

Insert into PROPERTY    (ID, TENANT_ID)  Values    (2, 1); 
Insert into PROPERTY    (ID, TENANT_ID)  Values    (3, 1); 
Insert into PROPERTY    (ID, TENANT_ID)  Values    (4, 1); 

Insert into PROPERTY_TYPE    (ID, 
    VALUE, PROPERTY_TYPE)  Values    (10, 'Colour', 2);    
Insert into PROPERTY_TYPE    (ID, 
    VALUE, PROPERTY_TYPE)  Values    (11, 'Trim Colour', 1);    
Insert into PROPERTY_TYPE    (ID, 
    VALUE, PROPERTY_TYPE)  Values    (12, 'Shipping Weight', 1); 
Insert into PROPERTY_TYPE    (ID, 
    VALUE, PROPERTY_TYPE)  Values    (13, 'Weight', 3); 

Insert into PROPERTY_DEPENDENCY    (PROPERTY_ID, 
    PARENT_PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (4, 3, 11); 
Insert into PROPERTY_DEPENDENCY    (PROPERTY_ID, 
    PARENT_PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (3, NULL, 10);
Insert into PROPERTY_DEPENDENCY    (PROPERTY_ID, 
    PARENT_PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (1, NULL, 12);    
Insert into PROPERTY_DEPENDENCY    (PROPERTY_ID, 
    PARENT_PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (2, 1, 13); 

--example of a property validated data insert

--item 201 with type 13 is the child of item 200 of type 12
Insert into CASE_PROPERTY    (ID, 
    PARENT_ID, CASE_ID, PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (200, NULL, 3000, 1, 12); 
Insert into CASE_PROPERTY    (ID, 
    PARENT_ID, CASE_ID, PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (201, 200, 3000, 2, 13); 

--bad data inserts

-- a property is parent to itself with an incorrect property_type_id 

Insert into CASE_PROPERTY    (ID, 
    PARENT_ID, CASE_ID, PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (202, 202, 4000, 3, 10);  
--should be 202, null,4000,3,10 

--a property is inserted with a parent that is not allowed 

Insert into CASE_PROPERTY    (ID, 
    PARENT_ID, CASE_ID, PROPERTY_ID, PROPERTY_TYPE_ID)  Values    (203, 200, 4000, 2, 13);  
--parent property should be 1 not 2
oracle database-design
  • 1 1 个回答
  • 1362 Views

1 个回答

  • Voted
  1. Best Answer
    Damir Sudarevic
    2013-03-16T09:25:38+08:002013-03-16T09:25:38+08:00

    不知道这是否对您有用,因为它需要进行相当多的更改,但是这个问题很有趣,所以我会尝试。

    这些将是主要的变化

    • 使用树闭包而不是参考层次结构的邻接列表。闭包表包含从每个父代到所有后代的路径,因此公开了所有可能的父子组合。

    请注意,对于树闭包,每个祖先节点都将自己指向自己作为后代,这意味着在CaseProperty递归中停止ID = ParentID而不是在ParentID is NULL

    我不清楚父母是否被允许成为任何祖先或只是第一步。闭包表公开祖先和所有后代,因此Level Difference被添加到TreeClosure,它的子类型为AllowedCombosfor LevelDifference in (0,1)。

    • 传播 AK{PropertyID, PropertyTypeID} 而不仅仅是PropertyID

    • 使用复合键CaseProperty


    在此处输入图像描述


    以下是模型的主要约束以阐明关系(您可能需要修改语法)

    ALTER TABLE Property ADD
      CONSTRAINT PK_PR  PRIMARY KEY (PropertyID)
    
    , CONSTRAINT AK1_PR UNIQUE (PropertyID ,PropertyTypeID)
    
    , CONSTRAINT FK1_PR FOREIGN KEY (PropertyTypeID)
             REFERENCES PropertyType(PropertyTypeID)
    ;
    
    
    
    ALTER TABLE TreeClosure ADD
      CONSTRAINT PK_TC PRIMARY KEY (AncestorID ,DescendantID ,AncestorTypeID ,DescendantTypeID)
    
    , CONSTRAINT FK1_TC FOREIGN KEY (AncestorID ,AncestorTypeID) 
                 REFERENCES Property(PropertyID ,PropertyTypeID)
    
    , CONSTRAINT FK2_TC FOREIGN KEY (DescendantID ,DescendantTypeID)
                 REFERENCES Property(PropertyID   ,PropertyTypeID)
    ;
    
    
    
    ALTER TABLE CaseProperty ADD
      CONSTRAINT PK_CP PRIMARY KEY (CaseID, PropertyID, PropertyTypeID)
    
    , CONSTRAINT FK1_CP FOREIGN KEY (CaseID)
                     REFERENCES Case(CaseID)
    
    , CONSTRAINT FK2_CP FOREIGN KEY (PropertyID ,PropertyTypeID)
                 REFERENCES Property(PropertyID ,PropertyTypeID)
    
    , CONSTRAINT FK4_CP FOREIGN KEY (ParentCaseID ,ParentPropertyID ,ParentPropertyTypeID)
             REFERENCES CaseProperty(CaseID       ,PropertyID       ,PropertyTypeID)
    
    , CONSTRAINT FK5_CP FOREIGN KEY (ParentPropertyID ,PropertyID   , ParentPropertyTypeID ,PropertyTypeID) 
            REFERENCES AllowedCombos(AncestorID       ,DescendantID , AncestorTypeID       ,DescendantTypeID)
    
    ;
    
    • 3

相关问题

  • 在数据仓库中实现多对多关系有哪些方法?

  • ORDER BY 使用文本列的自定义优先级

  • 舒服的sqlplus界面?[关闭]

  • 如何在数据库中找到最新的 SQL 语句?

  • 如何使用正则表达式查询名称?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve