我有 4 个这样相关的表(这是一个例子):
Company:
ID
Name
CNPJ
Department:
ID
Name
Code
ID_Company
Classification:
ID
Name
Code
ID_Company
Workers:
Id
Name
Code
ID_Classification
ID_Department
Run Code Online (Sandbox Code Playgroud)
假设我有一个classificationwith id = 20, id_company = 1。并且department有id_company = 2(代表另一家公司)。
这将允许创建来自两个公司的工人,因为分类和部门分别链接到公司。我不希望这种情况发生,所以我认为我的人际关系有问题,我不知道如何解决。
不使用 FK 约束是我公司的不为人知的规则。FK 约束仅在设计 ERD 时使用,在创建表时不使用。
据我的前辈说,在实际操作中,当我们处理紧急问题时,这些都是非常耗时的障碍。他说,当我们需要立即使用 INSERT/UPDATE/DELETE 语句时,约束会阻止这些语句的执行,并且在保持约束的同时编写语句也很耗时。我什至听说许多其他公司也在这样做。
虽然我有点理解这些挣扎,但我不确定这是否是一个好方法,因为它与我对 DB 的理解完全相反。这家公司也是我的第一份工作,所以我不知道其他公司是如何处理的。
实际上,您对此有何看法?这有道理吗?有更好的方法吗?其他公司在这方面的表现如何?
更新:对于韩国公司来说,这似乎是一种很常见的方法。我问了几个在别的公司工作的前辈,他们大多都说都是这样。甚至其中一个人在一家金融公司工作!有趣的...
我有一个表格,其中存储了用户在我网站上发布的所有论坛消息。消息层次结构是使用嵌套集模型实现的。
以下是该表的简化结构:
现在,该表看起来像这样:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| Id | Owner_Id | Parent_Id | nleft | nright | nlevel |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 1 | 1 | NULL | 1 | 8 | 1 |
| 2 | 1 | 1 | 2 …Run Code Online (Sandbox Code Playgroud) 假设我有一个表 A,它有两列:一列是 的 ID ThingA,另一列是 的 ID ThingB。主键是(ThingA, ThingB).
接下来,我有第二个表,但这次它仅限于表A中具有ThingB = 3. 主键是ThingA,因为ThingB是 3 的常数。
最初,我以为我可以简单地:
FOREIGN KEY (ThingA, 3) REFERENCES A(ThingA, ThingB)
Run Code Online (Sandbox Code Playgroud)
但我了解到事实并非如此,我必须为以下内容创建一个列ThingB:
ThingB INT NOT NULL DEFAULT(3) CHECK(ThingB = 3)
Run Code Online (Sandbox Code Playgroud)
然后,
FOREIGN KEY (ThingA, ThingB) REFERENCES A (ThingA, ThingB)
Run Code Online (Sandbox Code Playgroud)
有没有不需要额外列的替代方法,或者DEFAULT + CHECK?一种选择是持久化的计算列,但我也讨厌这个想法,因为它基本上是一种作弊,并且仍然添加了一个具有物理存储的新列。虽然它本身INT不会很大,但在几个表中有几百万行需要它,我宁愿不维护额外的列。
下面是示例 DDL 来说明这种情况:
CREATE TABLE Test1
(
ThingA INT NOT NULL,
ThingB INT NOT NULL,
PRIMARY …Run Code Online (Sandbox Code Playgroud) foreign-key database-design sql-server constraint sql-server-2014
我目前在两个实体之间有一个外键,我想让这种关系以其中一个表的 entityType 为条件。这是表的层次结构,这是通过从子级到父级的FK 引用完成的
Store
/ \
Employees \
TransactionalStores
/ | \
Kiosks | BrickMortars
Onlines
Run Code Online (Sandbox Code Playgroud)
我目前有从员工到商店的 FK 关系
ALTER TABLE Employees ADD CONSTRAINT Employee_Store
FOREIGN KEY (TransStoreId)
REFERENCES TransactionalStores(StoreId)
Run Code Online (Sandbox Code Playgroud)
我想添加条件:
WHERE TransactionalStores.storeType != 'ONLINE_TYPE'
Run Code Online (Sandbox Code Playgroud)
这是可能的还是我必须将 TransactionalStores 子类化为两个新的子类型(例如 PhysicalStores 和 VirtualStores)
我有一个应用程序,它在 SQL Server 2008 数据库(非集群)中创建了数百万个表。我想升级到 SQL Server 2014(集群),但在负载下时遇到错误消息:
“数据库中已经有一个名为'PK__tablenameprefix__179E2ED8F259C33B'的对象”
这是系统生成的约束名称。它看起来像一个随机生成的 64 位数字。由于大量表,我是否可能看到冲突?假设我有 1 亿张表,我计算出在添加下一张表时发生碰撞的可能性不到 1 万亿分之一,但这是假设均匀分布的。SQL Server 是否有可能在 2008 和 2014 版本之间更改其名称生成算法以增加冲突的几率?
另一个显着差异是我 2014 年的实例是一个集群对,但我正在努力形成一个假设,为什么会产生上述错误。
PS 是的,我知道创建数百万个表是疯狂的。这是我无法控制的黑盒 3rd 方代码。尽管疯狂,但它在 2008 版中有效,现在在 2014 版中无效。
编辑:仔细检查,生成的后缀似乎总是以 179E2ED8 开头 - 这意味着随机部分实际上只是一个 32 位数字,每次添加新表时,冲突的几率仅为 50 分之一,这与我看到的错误率更接近!
我想向一个非常大的表添加一个检查约束。就像是:
ALTER TABLE "accounts" ADD CONSTRAINT "positive_balance" CHECK ("balance" >= 0);
Run Code Online (Sandbox Code Playgroud)
不幸的是 PostgreSQL 9.3 在约束检查完成之前阻止读取或写入。我通过启动一个事务,运行ALTER TABLE,然后打开第二个事务并检查在第一个事务完成之前我无法从表中读取或写入来验证这一点。
有什么办法可以在CHECK不锁定表的情况下添加此约束?
这是一个简单的表,其中记录可以引用同一个表中的父记录:
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
parent_id INT NULL,
num INT NOT NULL,
txt TEXT NULL,
FOREIGN KEY (parent_id) REFERENCES foo(id)
);
Run Code Online (Sandbox Code Playgroud)
由于增加了其他字段值之一 ( num) 在父记录和子记录之间必须相同的要求,我认为复合外键应该可以解决问题。我将最后一行更改为
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
Run Code Online (Sandbox Code Playgroud)
并得到错误:没有唯一约束匹配给定键的引用表 "foo"。
我可以很容易地添加这个约束,但我不明白为什么它是必要的,当引用的列 ( id) 之一已经保证是唯一的?在我看来,新的约束将是多余的。
我正在尝试创建一个新表,其中的列后跟它们的约束,如下所示。
Create tblTest(
columns..
..
..
Gender int,
Constraint DF_tblTest_Gender Default 3 For Gender,
..
..
..
)
Run Code Online (Sandbox Code Playgroud)
但是,我在默认约束附近收到一条错误消息,
'for' 附近的语法不正确
在我正在进行的这个项目中,我需要将特定字段设置为唯一(不是问题!)但如果该字段为空,我希望忽略约束。在 Sql Server 2008 中,我使用如下所示的过滤索引,但这在早期版本的 SQL 中不可用!
CREATE UNIQUE NONCLUSTERED INDEX User_UserName_IUC
ON [User] (pinNr)
WHERE UserName IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
但我不认为这在 SQL Server 2005 中可用。事实上,这篇博客文章表明有一种使用触发器来检查唯一性的解决方法。有没有人有这样的例子?或者也许是另一种选择?
不幸的是,升级到 SQL Server 2008 不是这个特定客户端的选项!!