标签: database-design

设计模式 - 许多父表之一

我经常在数据库中遇到一种情况,其中给定的表可以 FK 到许多不同的父表中的一个。我已经看到了这个问题的两种解决方案,但都不是个人满意的。我很好奇你在那里看到了什么其他模式?有没有更好的方法来做到这一点?

一个人为的例子
假设我的系统有Alerts. 可以接收各种对象的警报——客户、新闻和产品。一个给定的警报可以只针对一个项目。无论出于何种原因,客户、文章和产品都在快速移动(或本地化),因此在创建警报时无法将必要的文本/数据拉入警报。鉴于此设置,我看到了两种解决方案。

注意:下面的 DDL 是针对 SQL Server 的,但我的问题应该适用于任何 DBMS。

解决方案 1 -- 多个可空 FKey

在此解决方案中,链接到多个表之一的表具有多个 FK 列(为简洁起见,下面的 DDL 不显示 FK 创建)。 好处- 在这个解决方案中,我有外键很好。FK 的空优化使得添加准确数据变得方便且相对容易。THE BAD Querying 不是很好,因为它需要N LEFT JOINS 或N UNION 语句来获取关联数据。在 SQL Server 中,特别是 LEFT JOINS 阻止创建索引视图。

CREATE TABLE Product (
    ProductID    int identity(1,1) not null,
    CreateUTC    datetime2(7) not null,
     Name        varchar(100) not null
    CONSTRAINT   PK_Product Primary Key CLUSTERED (ProductID)
)
CREATE TABLE Customer (
    CustomerID  int identity(1,1) …
Run Code Online (Sandbox Code Playgroud)

database-design

13
推荐指数
1
解决办法
2928
查看次数

如何设计这个数据库来避免循环依赖?

有两个表:

  1. 用户
  2. 地址

用户包含对地址的引用。

地址包含列 CreatedBy 和 ModifiedBy,这是对用户的引用。

如何设计此数据库以避免循环依赖?

database-design

13
推荐指数
2
解决办法
6670
查看次数

存储记录元数据的最佳实践

在数据库中存储单个记录的元数据的最佳实践是什么?

我需要在我的数据库中存储许多表的常见元数据,例如创建时间和上次更新时间。我找到了几种不同的解决方案:

  1. 将元数据直接存储在表中。

    优点:

    • 元数据直接链接到记录
    • 无需连接即可检索元数据

    缺点:

    • 需要大量重复列(除非使用继承)
    • 元数据和业务数据不分离
  2. 创建一个通用元数据表,并使用软外键将数据链接到正确的表和记录。

    优点:

    • 没有重复的列
    • 元数据与业务数据分离

    缺点:

    • 元数据和数据之间没有直接链接(不能使用 FK)
    • 联接需要附加条件
  3. 为每个需要元数据的表创建单独的元数据表。

    优点:

    • 元数据直接链接到记录
    • 元数据与业务数据分离

    缺点:

    • 需要很多额外的表
    • 需要大量重复列(除非使用继承)

是否有比我在这里提到的更多的选择、优点或缺点?存储这些元数据的最佳实践是什么?

postgresql database-design metadata

13
推荐指数
1
解决办法
5780
查看次数

将 600GB 表索引键数据类型从 INT 更改为 BIGINT 的最快方法

我需要将 600GB MySQL 表中的数据类型从 INT 更改为 BIGINT。该列具有唯一索引。我可能对 unsigned INT 很好,但我认为更改为 unsigned 或 BIGINT 将几乎相同的痛苦。该表的引擎是 InnoDB。什么会更容易:

  1. 更改表
  2. 复制结构和 INSERT INTO (SELECT *)
  3. 转储表和更改转储文件表定义
  4. 还要别的吗?

更新:根据要求,MySQL 5.5.15 版,没有外键并创建表:

 CREATE TABLE `tbl` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `user_id` int(11) NOT NULL,
    `created_at` datetime NOT NULL,
    `tid` bigint(20) NOT NULL,
    `t` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
    `f` tinyint(1) NOT NULL,
    `i_id` bigint(20) NOT NULL,
    `ir_id` int(11) NOT NULL,
    `r_c` int(11) NOT NULL,
    `r` tinyint(1) NOT NULL,
    `e` text CHARACTER SET …
Run Code Online (Sandbox Code Playgroud)

mysql database-design alter-table mysql-5.5

13
推荐指数
1
解决办法
3653
查看次数

电子商务订单表。保存价格,还是使用审计/历史表?

我正在设计我的第一个电子商务模式。我已经阅读了一段时间的主题,并且对 anorder_line_item和 a之间的关系感到有些困惑product

一个product可以被购买。它有各种细节,但最重要的是unit_price

Anorder_line_item有一个外键,指向product_id购买的、quantity购买的和unit_price客户购买产品的时间点。

我读过的大部分内容都说应该明确添加unit_priceon order_line_item(即不通过 引用product_id)。有道理,因为商店将来可能会改变价格,这会弄乱订单报告、跟踪、完整性等。

我不明白的是,为什么直接将unit_price值保存到order_line_item?

创建一个记录unit_pricea 更改的审计/历史表不是更好product吗?

order_line_item被创建,所述的外键product_audit表,并将该价格可以从那里检索(通过引用)。

在我看来,使用这种方法有很多好处(减少重复的数据、价格变化历史等),那么为什么不更频繁地使用它呢?我还没有遇到使用这种方法的电子商务模式的例子,我错过了什么吗?

UDPATE:我的问题似乎与Slowly Changed Dimension 相关。我仍然感到困惑,因为缓慢变化的维度与数据仓库和 OLAP 相关。那么,缓慢变化的维度类型可以应用于我的主要业务事务流程数据库 (OLTP) 吗?我想知道我是否混合了很多概念,非常感谢一些指导。

mysql schema database-design audit data-integrity

13
推荐指数
1
解决办法
6823
查看次数

强制约束“两个表”

我在 SQL 中对电气原理图建模时遇到了一些麻烦。我想捕获的结构是

  part ??????????? pin
   ?                ?
part_inst ?????? pin_inst
Run Code Online (Sandbox Code Playgroud)

其中“inst”是“instance”的缩写。

例如,我可能part将 LM358 运算放大器pin用作 1OUT、1IN-、1IN+、GND、2IN+、2IN-、2OUT 和 V CC。然后我可能会将这部分放在原理图上,创建 apart_inst和 8 pin_insts。

忽略数据字段,我对模式的最初尝试是

create table parts (
    part_id bigserial primary key
);
create table pins (
    pin_id bigserial primary key,
    part_id bigint not null references parts
);
create table part_insts (
    part_inst_id bigserial primary key,
    part_id bigint not null references parts
);
create table pin_insts (
    pin_inst_id bigserial primary key,
    part_inst_id bigint …
Run Code Online (Sandbox Code Playgroud)

postgresql foreign-key database-design referential-integrity polymorphic-associations

13
推荐指数
1
解决办法
5105
查看次数

CouchDB 和文档版本控制

我目前正在使用 CouchDB 开发一个 wiki-esque 应用程序,并试图实现一个文档版本控制方案。在我看来,有两种方法可以做到这一点:

  1. 将每个版本存储为单独的文档
  2. 将旧版本存储为单个文档的附件。

现在,我有一种#1 的工作形式。当用户编辑文档并保存时,后端首先将之前的修订复制到新文档中,然后保存新版本。每个文档都有一个 'history' 数组,其中包含每个版本的数据(旧版本的文档 _id、时间戳、编辑器等)。

由于这个历史数组对于经常更新的文档来说可能会变得很长,我有一个视图可以在正常读取期间获取一个没有历史记录的文档(以及另一个用于获取历史记录的视图)。

我的问题是:我对我目前的方法感到不安,并一直在考虑改用“依恋”方法。但我不确定。我希望有人比我更了解 CouchDB(我只在这工作了几个星期——这是我第一个使用 CouchDB 和 NoSQL 的项目)可以告诉我每个项目的优缺点方法。或者是否还有其他一些我忽略的版本控制方案?

database-design couchdb

12
推荐指数
1
解决办法
3060
查看次数

5+ 列主键对大型(1 亿+)表有害吗?

我正在阅读一些现实生活中的数据库问题,一个项目有一个 1 亿行多的表,其中有 5 列作为其主要内容。我认为这很糟糕,但谁能告诉我究竟是为什么?

该表是一种微型汇总/聚合表,因此 5 列类似于(day、market_id、product_id...)。起初我认为一个 5 列的主键并不理想,但我越想,我真的想不出一个很好的理由为什么它很糟糕。

这是与一半的公司工程师进行的深夜讨论。刚刚有人提到这是一个糟糕的设计,一位高级工程师表示同意,但没有人真正了解原因。因此试图为自己研究这件事!

mysql database-design primary-key

12
推荐指数
1
解决办法
2876
查看次数

存储 IP 地址 - varchar(45) 与 varbinary(16)

我将创建一个包含两个字段的表 - IDasBIGINTIPAddressasvarchar(45)或者varbinary(16)。这个想法是存储所有唯一的 IP 地址并使用引用ID而不是IP address其他表中的实际地址。

通常,我将创建一个存储过程,该过程返回ID给定的IP address或(如果未找到地址)插入地址并返回生成的ID.

我期望有很多记录(我无法确切说出有多少),但我需要尽快执行上面的存储过程。所以,我想知道如何以文本或字节格式存储实际的 IP 地址。哪个会更好?

我已经编写了SQL CLR用于将 IP 地址字节转换为字符串和反向转换的函数,因此转换不是问题(同时使用IPv4IPv6)。

我想我需要创建一个索引来优化搜索,但我不确定我应该将该IP address字段包含在聚集索引中,还是创建一个单独的索引以及使用哪种类型的搜索会更快?

database-design sql-server sql-server-2012 sql-clr nonclustered-index

12
推荐指数
2
解决办法
2万
查看次数

不测试一个功能可以吗?

是否有任何时候您对您的语言/数据库/系统变得如此熟悉,以至于无需测试新功能/配置/查询/等。在您的系统中实施之前通过包含/模拟测试(特别是关于修改数据的功能)?还是在测试环境中通过模拟来测试新查询总是必不可少的?

进一步说明,很明显,测试总是最安全的。但是,有没有一种方法可以确定何时风险如此之小以至于测试不值得付出努力?另一种表述方式:何时或曾经是专业的实践来承担风险来实现一个功能?

此外,让我们假设所有内容都已备份,因此,在最坏的情况下,数据可能通过一些努力来恢复数据。

有人可以引用具体的专家经验来解决这个问题吗?请在适当/可能的情况下包括参考文献。

database-design testing learning features configuration

12
推荐指数
1
解决办法
304
查看次数