我试图了解使用 1 张大桌子还是许多小桌子更好。我已经通过网络准备好了这取决于每种情况,所以我想根据下面的示例提出任何建议:
假设我想创建一个包含资产所有特征的数据库。资产可以分为不同的资产类别(即股票、债券、现金等)。所有资产类别都具有相似的特征(即 ID 代码、发行人名称)并且一些资产具有特定特征(债券具有到期日而股票没有)。所以我的问题是我是否应该使用一个大表,当资产不适用时,该表将保留为 NULL(如下所示)

还是每次我需要生成报告时,我应该使用几个表作为并加入它们?(如下所示)

每种情况的利弊是什么?例如,如果我有 1m 个不同的 ID 代码,它是否需要为 1 表选项增加空间,而使用多表选项查询性能会显着下降?
如果每种类型的独特特征是 50 种,并且有 10 种不同的资产类别,该怎么办?我应该创建一个 50 x 10 = 500 列的表(每行的大部分列都为 NULL)还是应该有 10 个不同的表并在我想创建报告时使用 LEFT JOIN?
我有一个连接对象浏览器,我希望允许用户查看他们连接到的各种数据源。对象的查看器看起来像这样:
连接:Remote.1234.MySQL(3级源)
连接:Remote.abc.ElasticSearch(2级源)
连接:Local.xyz.MongoDB(3级源)
连接:Local.xyz.SQLServer(4级源)
换句话说,“源”是具有已知数量的级别和每个级别的已知“名称”的层次结构。虽然整个层次结构是可变的,但任何给定源的层次结构将始终具有相同的级别数和名称。建立关系模型的好方法是什么?我的想法是:
联系:
来源类型:
源类型级别映射:
database relational-database hierarchical-data database-schema
我一直在阅读有关EAV数据库的信息,大多数缺点似乎都与真的,真的,错误的EAV设计或从数据生成报告的难度有关。
通常,当您看到人们抱怨EAV时,他们使用少于三个的表来尝试复制RDBMS中单独的表+列的功能。有时,这意味着将所有内容(从小数到字符串)都存储在单个TEXT值列中。EAV还会破坏数据完整性的安全保护措施,如果您不小心的话,这可能会很糟糕。
但是,EAV确实提供了一种轻松的方式来跟踪历史数据,并允许我们在SQL和键值存储系统之间来回移动系统的某些部分。
如果我们根据类型区分不同的实体属性该怎么办。除了与特定属性和实体相关的正确索引值之外,这还使我们仍然可以处理belongsTo,Has,HasMany和HasManyThrough关系。
考虑以下两个基本实体
products (price -> decimal, title -> string, desc -> text, etc...)
attributes
options
[...]
int
datetime
string
text
decimal
relation
[id,foreign_key]
users (gender -> options, age -> int, username -> string, etc...)
attributes
options
[...]
int
datetime
string
text
decimal
relation
[id,foreign_key]
Run Code Online (Sandbox Code Playgroud)
众所周知,用户资料和产品是世界上最多样化的产品。每个公司处理它们的方式都不一样,并且针对他们的需求具有不同的“列”或“属性”。
以下是如何处理多个(嵌套和/或关系)实体的视图。
想法是,对于每个实体都有此主属性表,然后该主表指定如何查找和解释这些值。这使我们能够处理特殊情况,例如指向其他实体的外键以及诸如“选项”或十进制数字之类的东西。
entity_type {id,type,//即“博客”,“用户”,“产品”等。created_at}
entity {
id,
entity_type_id,
created_at
}
attr {
id,
entity_id,
type,
name,
created_at
}
option {
id,
attr_id, …Run Code Online (Sandbox Code Playgroud) 我在 Postgres 中有一个表,其中包含Things。这些事物中的每一个都可以是以下 3 种类型中的一种:
本质上,用对象术语来说,有一个 AbstractThing,由 SuperThingA 或 SuperThingB 以不同方式扩展,并且 Thing 表上的所有记录要么未扩展,要么以两种方式之一扩展。
为了在事物表上表示这一点,我有许多所有类型的事物共有的字段,并且我在 SuperThingA 和 SuperThingB 表中有 2 个可选的 FK 参考列。
理想情况下,我希望两者都具有“FK IF NOT NULL”约束,但这似乎不可能;据我所知,我所能做的就是使这两个字段都可以为空,并依靠使用代码来维护 FK 关系,这非常糟糕。这似乎在其他数据库中是可行的,例如 SQL Server,根据SQL Server 2005: Nullableforeign Key Constraint,但到目前为止我在 PG 中没有找到任何方法
我还能如何处理这个问题 - 当这些字段中的任何一个不为空时检查值并检查哪个父表上存在该值的插入/更新触发器?这在事物表上插入有限的小型父表上也许是可行的(公平地说,这里的情况基本上就是这样——每个父表中不超过几百条记录,并且事物上的插入数量很少)表),但在更一般的情况下,如果一个或两个父表很大,则插入时将成为性能黑洞
目前,对于 FK 关系,这一点并未强制执行。我已经查看了 PG 文档,并且似乎很确定我不能拥有可选的 FK 关系(这是可以理解的)。它给我留下了一个像这样的表定义:
CREATE TABLE IF NOT EXISTS Thing(
Thing_id int4 NOT NULL,
Thing_description varchar(40),
Thing_SuperA_FK int4,
Thing_SuperB_FK char(10),
CONSTRAINT ThingPK PRIMARY KEY (Thing_id)
) …Run Code Online (Sandbox Code Playgroud) 我在软件中使用 Firebird 数据库并发现了一个问题
\n\n我有两张桌子,适合两种不同类型的客户:
\n\nclientM(\n\n rfcM varchar(12) primary key\n\n some other data \n\n)\n\nclientF(\n\n rfcF varchar(13) primary key\n\n some other data\n\n)\nRun Code Online (Sandbox Code Playgroud)\n\n(长度是固定的,因为它是 M\xc3\xa9xico 中我期望用户输入的数据的标准)
\n\n问题来了,我需要创建第三个表:
\n\nclientPayment(\n\n rfcClient varchar(13)\n\n some other data\n\n)\nRun Code Online (Sandbox Code Playgroud)\n\n并且该字段必须有一个引用 clientM.rfcM 和 clientF.rfcF 的外键,因此我可以使用同一个表来存储来自两种类型客户的付款
\n\n我可以让第三个表不带外键,但希望添加一个并避免用户输入不正确的数据
\n我正在构建一个具有以下两个表的 Postgres 数据库:
项目(id、startDate 等...)和员工(id、name 等...)
我想跟踪员工为项目添加的贡献类型。例如,员工#1 可能是项目 1 的“工程师”和项目 2 的“经理”。我也不希望限制员工可以对某个项目做出的贡献数量。因此,员工#1 可以是单个项目的“工程师”和“经理”。
我的第一直觉只是在两个标题为 ProjectEmployees 或其他东西之间建立多对多关系,并将 projectId、employeeId 和tributionType 存储为一个字符串,该字符串只会从枚举中获取值,而不必处理拼写错误或任何相关问题。
我的主要问题是这是否是一种不好的做法。我的另一个想法是将每种贡献类型拆分到自己的表中。因此,不是 EmployeeProjects 表,而是诸如 ProjectEngineers、ProjectManagers 等的表……并且不是将贡献类型存储为列,而是隐式在我正在使用的表中,并且该表只需要存储项目 ID 和员工 ID。该数据库中有更多的表具有类似的关系,其中不同表之间存在多对多关系,但每个关系可能是许多“类型”关系中的一种。对于每种类型的关系,将所有这些都拆分为单独的表是否更明智?或者像我的第一个想法一样在更通用的表中跟踪关系类型更好吗?
我想要的结果是能够有效地查看员工参与的所有项目贡献(和类型),以及查看项目的所有贡献者 + 贡献者类型。
foreign-keys ×3
sql ×3
postgresql ×2
6nf ×1
database ×1
firebird ×1
key-value ×1
option-type ×1
relationship ×1