标签: database-design

为什么我不应该为多个关系使用一张表?

假设我的数据库中有多个关系,例如 Store、Employee 和 Sale,并且我想用简单的二元关系连接对。我个人会使用由外键组成的自然键创建名为 Employee_Store 和 Employee_Sale 的表。

现在,我的同事坚持为多个关系创建一张表。对于上面的示例,可能有一个名为 EmployeeLinks 的表:

EmployeeLinks(
    IdLink int PK, 
    IdEmployee int FK null,
    IdStore int FK null,
    IdSale int FK null,
    LinkType int not null
)
Run Code Online (Sandbox Code Playgroud)

请帮助我说明为什么这不是一个好主意的充分理由。我有自己的论点,但我想将它们保密并听取您的公正意见。

编辑:

最初上表没有主键 (!)。因为外键允许为空,所以代理键是唯一的选择。

database-design

14
推荐指数
2
解决办法
2650
查看次数

数据库重新设计机会:此传感器数据收集使用什么表设计?

背景

我有一个由大约 2000 个传感器组成的网络,每个传感器都有大约 100 个数据点,我们每隔 10 分钟收集一次。这些数据点通常是 int 值,但有些是字符串和浮点数。这些数据应该存储 90 天,如果可能的话,更多并且仍然有效。

数据库设计

当最初负责这个项目时,我编写了一个 C# 应用程序,为每个传感器编写逗号分隔的文件。当时没有那么多,当有人想查看趋势时,我们会在 Excel 中打开 csv 并根据需要绘制图表。

事情发展了,我们切换到了 MySQL 数据库。我为每个传感器创建了一个表格(是的,我知道,很多表格!);它运行良好,但有一些限制。有这么多表,显然不可能编写一个查询,在查找特定值时会在所有传感器中查找数据。

对于下一个版本,我切换到 Microsoft SQL Server Express,并将所有传感器数据放入一个大表中。这也有效,并让我们进行查询以在所有感兴趣的传感器中查找值。但是,我遇到了 Express 版本的 10GB 限制,并决定切换回 MySQL 而不是投资 SQL Server Standard。

问题

我对 MySQL 的性能和可扩展性很满意,但我不确定坚持所有数据在一个表中的方法是否最好。单个表中的 10GB 似乎要求不同的设计。我应该提到的是,仍然需要查询数据以绘制图形,而且我担心绘制图形的查询会出现性能问题,例如,一个传感器在整个 90 天内的温度数据。(换句话说,图形应该是快速生成的,而无需等待 SQL 对成堆的数据进行排序以隔离感兴趣的传感器。)

我应该以某种方式拆分此表以提高性能吗?或者有这么大的桌子也不是什么稀奇事?

我在 Sensor ID 和 Timestamp 列上有索引,这几乎是任何查询的定义边界。(即从时间 A 到时间 B 获取传感器 X 的数据)。

我已经阅读了一些关于分片和分区的内容,但在这种情况下不觉得这些是合适的。


编辑:

根据到目前为止的评论和答案,一些额外的信息可能会有所帮助:

非无限期存储:目前我不存储超过 90 天的数据。每天,我都会运行一个查询来删除超过 90 天的数据。如果将来它变得重要,我会存储更多,但现在已经足够了。这有助于控制大小和高性能(呃)。

引擎类型:最初的 MySQL 实现使用了 MyISAM。这次为新实现(一个数据表而不是多个)创建表时,他们默认为 InnoDB。我不相信我对其中一个有要求。

归一化:当然还有除了数据采集表之外的其他表。这些支持表存储诸如传感器的网络信息、用户的登录信息等内容。没有太多需要规范化的内容(据我所知)。数据表有这么多列的原因是每个传感器有这么多变量。(多个温度、光照水平、气压等)对我来说标准化意味着没有冗余数据或重复组。(至少对于 1NF。)对于给定的传感器,在特定时间存储所有值需要一行数据,并且那里不涉及 1:N 关系(我看到)。 …

mysql database-design partitioning

14
推荐指数
2
解决办法
4890
查看次数

存储来自传感器阵列的大量数据

我的任务是实施一个解决方案(应用程序和数据库)来存储来自巨大传感器阵列的数据样本。该阵列目前由大约 20,000 个传感器组成,但很快就会增长到 100,000 个传感器。每个传感器每 10 秒发送一个数据样本,每个样本的大小为 28 字节。

因此,进行求和会导致:

  • 每个传感器每天 8640 个样本
  • 每个传感器每天 242kB 的数据
  • 每天 8.64 亿个样本

现在我一直想知道存储/检索数据的最佳方法是什么?我在指定软件后“加入”了这个项目,所以它需要在使用 SQL Server 的 Windows 平台上实现。

我目前的解决方案是创建一个带有两个表的数据库来存储数据样本。第一个用作第二个的索引,将整理的样本存储在每个传感器每天的二进制字段中:

Table 1:

  RecordID - BigInt - Identity
  SensorID - BigInt - Primary Key
  Date - DateTime - Primary Key (yyyy-mm-dd)

Table 2:

  RecordID - BigInt - Primary Key (from an insert into Table 1)
  Data - Binary 
Run Code Online (Sandbox Code Playgroud)

基本上我会将来自所有传感器的样本写入临时文件(每个传感器 1 个)。在每天结束时,我将在表 1 中创建一个条目,使用生成的 RecordID 并将文件转储到表 2 中的数据字段中。

这样,我最终每天只有 100,000 个条目进入表,而不是 8.64 亿个条目。数据应该在 LAN 或高速 WAN …

database-design sql-server

14
推荐指数
1
解决办法
7346
查看次数

列存储索引中的列顺序重要吗?

我有一个包含约 2 亿行和约 15 列的表。我打算COLUMNSTORE在我的表上创建一个索引。

根据我在列存储索引中使用的列顺序,性能是否会有任何变化?如果是,其背后的逻辑是什么?

index database-design sql-server sql-server-2012 columnstore

14
推荐指数
1
解决办法
3441
查看次数

调查数据库设计:将答案与用户相关联

我正在做一个调查数据库的概念模型。

目标是存储用户给出的答案(它将是一个 Android 应用程序)。

我有三个实体:用户、问题和选​​项。

一个问题将有一个或多个选项(例如:您有多少员工? 1-40、40-1000、+1000)。

选项将有一个文本 (1-40) 和一个值(用户选择的值)。

用户将选择这些选项中的一个(或多个)。

我的概念设计是:

在此处输入图片说明

我不知道如何将答案与用户相关联。

我如何表示这种关系?
我是否有另一个实体来表示期权价值?

该模型将存储问题和预制答案(提供的答案),并允许它们在不同的调查中重复使用。

我必须代表这样的问题:

在此处输入图片说明

这个问题与这个问题有关:Survey database design: first version。有错误吗?

database-design

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

对多个查询列使用相同的 CASE WHEN 条件

是否有“更好”的方法来重写SELECT多个列使用相同CASE WHEN条件的子句,以便条件只检查一次?

请参阅下面的示例。

SELECT
    CASE testStatus 
        WHEN 'A' THEN 'Authorized'
        WHEN 'C' THEN 'Completed'
        WHEN 'P' THEN 'In Progress'
        WHEN 'X' THEN 'Cancelled'
    END AS Status,

    CASE testStatus 
        WHEN 'A' THEN authTime
        WHEN 'C' THEN cmplTime
        WHEN 'P' THEN strtTime
        WHEN 'X' THEN cancTime
    END AS lastEventTime,

    CASE testStatus 
        WHEN 'A' THEN authBy
        WHEN 'C' THEN cmplBy
        WHEN 'P' THEN strtBy
        WHEN 'X' THEN cancBy
    END AS lastEventUser
FROM test
Run Code Online (Sandbox Code Playgroud)

在非 sql 伪代码中,代码可能如下所示:

CASE testStatus
    WHEN …
Run Code Online (Sandbox Code Playgroud)

oracle database-design best-practices oracle-10g

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

对子集聚合的建模约束?

我正在使用 PostgreSQL,但我认为大多数高端数据库必须具有一些类似的功能,而且,它们的解决方案可能会启发我的解决方案,所以不要考虑这个特定于 PostgreSQL 的解决方案。

我知道我不是第一个尝试解决这个问题的人,所以我认为这里值得一问,但我正在尝试评估建模会计数据的成本,以便从根本上平衡每笔交易。会计数据是仅附加的。此处的总体约束(以伪代码编写)可能大致如下:

CREATE TABLE journal_entry (
    id bigserial not null unique, --artificial candidate key
    journal_type_id int references  journal_type(id),
    reference text, -- source document identifier, unique per journal
    date_posted date not null,
    PRIMARY KEY (journal_type_id, reference)
);

CREATE TABLE journal_line (
    entry_id bigint references journal_entry(id),
    account_id int not null references account(id),
    amount numeric not null,
    line_id bigserial not null unique,
    CHECK ((sum(amount) over (partition by entry_id) = 0) -- this won't work
);
Run Code Online (Sandbox Code Playgroud)

显然,这样的检查约束永远不会起作用。它按行操作,可能会检查整个数据库。所以它总是会失败并且做起来很慢。

所以我的问题是对这种约束进行建模的最佳方法是什么?到目前为止,我基本上已经研究了两个想法。想知道这些是否是唯一的,或者是否有人有更好的方法(除了将其留给应用程序级别或存储过程)。

  1. 我可以借用会计界关于原始分录和最终分录(普通日记帐与总分类帐)之间差异的概念的一页。在这方面,我可以将其建模为附加到日志条目的日志行数组,对数组强制执行约束(在 PostgreSQL 术语中,从 …

postgresql database-design data-integrity

14
推荐指数
1
解决办法
2272
查看次数

31亿行数据如何管理?

我目前的任务是为相对大量的数据实施存储模式。将主要访问数据以确定当前data point值,但我还需要跟踪过去六个月的历史数据趋势/分析。

加入最近要求跟踪min/ max/sum在过去的小时值。

注意:理想情况下,我想考虑 MongoDB 选项,但我需要先证明我已经用完了 SQL-Server 选项。

数据

下表表示主要数据源(最常查询)。该表将有大约 500 万行。数据更改将主要是初始数据加载后UPDATE非常偶然的INSERT语句。我选择了对数据进行聚类,dataPointId因为您将始终选择all values for a given data point.

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) …
Run Code Online (Sandbox Code Playgroud)

database-design sql-server

14
推荐指数
1
解决办法
3万
查看次数

跨数据库共享单个主键序列?

在所有表中使用单个序列作为主键(而不是主键对于给定表是唯一的,它对于所有表都是唯一的)是否可以接受?如果是这样,客观上是否比跨表使用单个主键序列更好。

我是一名初级软件开发人员,而不是 DBA,所以我仍在学习良好数据库设计的许多基础知识。

编辑:如果有人想知道,我最近阅读了我们公司的一位 DBA 对数据库设计的评论,他提到设计没有在整个数据库中使用单个主键是一个问题,这听起来与到目前为止我已经学会了。

Edit2:要回答评论中的问题,这是针对 Oracle 11g 的,但我想知道非数据库特定级别。如果这个问题确实取决于数据库,我很想知道原因,但在这种情况下,我会寻找特定于 Oracle 的答案。

database-design primary-key

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

对于大型应用程序,在同一数据库中不同模式的表上创建外键是个坏主意吗?

我正在将一个大型 pl/sql 基于 web 的应用程序转移到专用服务器。该应用程序位于一个包含 70 个程序代码包的模式中。这个应用程序是在不同的时间大约有 15 人完成的。我们通常的做法是在不同模式中的引用表上创建外键,因为它非常方便并且保持数据库非常干净,因为我们不需要在不同模式中保留相同的引用表。

但无论如何,我的 DBA(他用 DB 创建了新实例并将我的应用程序复制到 Solaris 区域内)今天说得很严厉,“不同模式上的外键是邪恶的,你需要销毁它!”。他没有解释他的观点。

在大型应用程序中这样做真的很糟糕吗?

schema oracle foreign-key database-design

14
推荐指数
1
解决办法
6860
查看次数