如何为丢失主键和外键信息的数据库生成ERD/UML?

How to generate ERD/UML for a database which has lost its primary key and foreign key information?

我有 table 结构良好的数据库的创建脚本。 但是,出于某种原因,table 创建脚本不包含主键或外键信息。

为使用这些脚本创建的数据库生成 ERD/UML 的最佳方法是什么 - 假设索引完好无损。是否有任何工具可用于检查列名并生成 ERD/UML?

我应该手动执行此操作吗?

您问题的答案 - 我应该手动执行此操作吗? - 是的,恐怕。

让我们考虑自动检测主键和外键的可能性。不管这样的算法是否已经存在或者是否会由您自己编写,它都必须从给定的数据库方案中确定哪些属性组合符合 PK 和 FK。

有一个简单的案例,但我怀疑这对你的数据库来说不是真的,否则你不会问这个问题。如果有名称约定(非常值得推荐),例如仅调用每个 PK id 和每个 FK <referenced table>_id,然后从 table 定义的句法属性可以清楚 PK 和 FK 所在的位置。但是你的数据库定义会自己回答你的问题。

另一种方式是 table 及其属性的语义。例如,如果您有一个包含 place_of_birth 属性的 person table,并且只有一个名为 city 的 table 可能包含此类位置,那么很可能你找到了 FK。但是这种推理很难自动化,因为它需要大量关于数据库基础领域的知识,以及该领域术语的含义和关系。

剩下的算法可能性基于数据库键的正式定义。键是 table 中每条记录具有唯一值的属性或属性组合。不幸的是,这是一个 extensional 定义,即它指的是您在特定时间点拥有的数据库内容。例如,假设您有一个 table person,其属性为 first_namelast_name。您可以找到或编写一种算法来检测一个或多个列是否符合关键候选条件,并且今天它可能会确定名字和姓氏是否符合条件,因为 table 中没有两条记录共享相同的值对他们。但是明天,一个叫 Jack Miller 的人可能会出现在你的数据库中,而另一个 Jack Miller 也存在,这将使你的 PK 假设无效。

因此,一个 stable 键的概念必须伴随着一个 intensional 论证,一个领域法则确保键的特定组合是并将保留每个域对象都是唯一的。

通常,通过引入人工密钥(如 id)可以避免这种困难。虽然可以推荐这样做,但恐怕您的数据库并没有太严格地遵循这一点,否则您会注意到它并且它至少可以部分解决您的问题。

来到 FKs 时,会出现类似的困难。从句法上讲,table t1 中的每个属性组合其值组合是另一个 table t2 中属性组合的子集可能是 [=56] 的 FK =].但即使在您已经确定主键的简单情况下,也许对于一些语义清晰的 tables 包含参考数据,算法应该如何判断,对于包含从 1 到 100 的值的潜在 FK,哪个 tables 具有从 1 到(至少)100 的键被引用?

所以恐怕主要任务将是手动完成的,或者更确切地说,是使用一些领域知识在大脑中执行。在应用自下而上的方法分析价值组合的范围之前,应该进行一些自上而下的推理。您域的主要业务对象是哪些,如何可以识别它们,以及如何它们需要相互关联?一旦找到假设,算法验证就很容易了。要伪造关键候选者,请执行类似

的查询
select key_candidate, count(*) as ct
from table
group by key_candidate
having ct > 1

并且如果它产生多于零条记录,则 key_candidate 不能成为键。要伪造外键,执行

select *
from table t
where not exists (
   select *
   from referenced_table rt
   where t.fk_candidate = rt.key
)

如果它产生多于零条记录,则 fk_candidate 不是 FK 或 key 不是要引用的预期键。但是那些算法论证只是对你的语义研究的补充。

任务的手动部分基本上是从以数据为中心的角度进行业务分析。这既费时又乏味。从主题专家那里获得尽可能多的帮助。发现业务规则,以及主题专家一直处理的实体。了解他们如何识别这些实体的实例。

TAM 在他的回答中概述了此任务的可自动化部分。