标签: database-design

我应该使用 UUID 以及 ID

由于各种原因,从日志记录到延迟关联,我已经在我的系统中使用 UUID 有一段时间了。当我变得不那么天真时,我使用的格式发生了变化:

  1. VARCHAR(255)
  2. VARCHAR(36)
  3. CHAR(36)
  4. BINARY(16)

当我到达最后一个时BINARY(16),我开始将性能与基本的自动增量整数进行比较。测试和结果如下所示,但如果你只是想总结,表示INT AUTOINCREMENTBINARY(16) RANDOM对数据相同的性能范围高达20万(该数据库已预先填充之前测试)。

我最初对使用 UUID 作为主键持怀疑态度,事实上我仍然如此,但是我看到这里有潜力创建一个可以同时使用两者的灵活数据库。尽管许多人强调两者的优点,但使用这两种数据类型抵消了哪些缺点?

  • PRIMARY INT
  • UNIQUE BINARY(16)

此类设置的用例将是表间关系的传统主键,唯一标识符用于系统间关系。

我本质上试图发现的是两种方法之间的效率差异。除了使用的四倍磁盘空间(在添加额外数据后可能在很大程度上可以忽略不计)之外,在我看来它们是相同的。

架构:

-- phpMyAdmin SQL Dump
-- version 4.0.10deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Sep 22, 2015 at 10:54 AM
-- Server version: 5.5.44-0ubuntu0.14.04.1
-- PHP Version: 5.5.29-1+deb.sury.org~trusty+3

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 …
Run Code Online (Sandbox Code Playgroud)

mysql performance database-design uniqueidentifier

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

对于圣经希伯来语,我应该使用哪种排序规则?

对于圣经希伯来语,我应该使用哪种 SQL Server 排序规则?所考虑的数据库需要适应变音符号(即元音、重音、比喻等)。

database-design sql-server collation configuration sql-server-2017

19
推荐指数
2
解决办法
1929
查看次数

除了添加大量列之外,是否有用于存储许多布尔标志的通用模式?

我有一堆需要与用户帐户关联的布尔值。它们需要在真假之间切换,尽管不是特别频繁——它们被阅读的次数将比写入的次数更多。大多数情况下,它们只会从 False 设置为 True 一次,但情况并非总是如此。

现在我正在考虑将列附加到用户表中:

用户身份 other_user_cols did_a did_b did_c
1 ... 错误的 真的 错误的
2 ... 错误的 错误的 错误的
3 ... 真的 错误的 错误的

问题是,有很多这样的布尔列。

假设您需要添加 100 列。这真的仍然是最好的方法吗?

认为:

  • 它不会非常稀疏 - 大多数用户会在某个时候切换大多数布尔值
  • 布尔值没有以自然可以更好地组织的方式在逻辑上相关
  • 可能需要不时添加新的
  • 标志直接与每个用户相关联,除了单个布尔值之外不需要其他信息

我觉得这一定是一个非常常见的模式,但是这种将更多布尔列塞入我的表的方式似乎相当混乱。有没有更典型的方法来做它更干净一点?或者这实际上是最好的方法?

为此,我正在使用 Postgres。

以下是我考虑过的一些替代方案:

  • 序列化为字符串的 json 列表(= 列名)。这听起来比原来的更混乱,如果我想对数据进行任何严肃的 SQL 操作,也不理想
  • 使用数字和按位运算 - 不确定这有多受支持,以及需要对单个标志进行操作/查找的类似问题
  • 有一个单独的表,如:
用户身份 标志名称 价值
1 did_a 错误的
1 did_b 错误的
3 did_a 真的

作为替代方案,这对我来说似乎是最合理的,但不确定是否真的值得麻烦,或者是否有更好的方法。

postgresql database-design

19
推荐指数
3
解决办法
2401
查看次数

存储大量列的好方法是什么?

我在决定如何将这些数据存储在我的数据库中时遇到了问题。关于最好的方法有什么建议吗?我对数据库知之甚少,我可能会补充。

我的数据格式如下,但不是 4,列数约为 240,因此每个日期都有 240 个与之关联的唯一值:

Date/Time 200,00 202,50 205,00  
2010.11.12  13:34:00  45,8214 43,8512  41,5369   
2010.11.12  13:35:00  461,9364  454,2612  435,5222 
Run Code Online (Sandbox Code Playgroud)

此外,行与 DataSites 相关联。

我的第一个想法是有一个像这样的表:DataID (pk)、DataSiteID、ParameterID、Date、Value,在 DataSite、Parameter 和 Date 上有一个索引。ParameterID 指的是另一个存储输入列标题的表 (200,00 202,50 205,00 ...)。

我的第二个想法是拥有一个包含所有 240 多列的表格。我想出了其他一些方法,但它们也很不令人满意。

我的第一个解决方案的问题(不是那么大的问题,但我不喜欢它)是日期和 DataSiteID 将重复输入行中的所有 240 个值,因此它使用了很多的额外空间。

每年会有大约40GB的数据进来(上面的文本格式),数据会通过DataSite、Parameter和Date进行搜索。传入的数据量很可能会在一年左右的时间内翻两番。

有什么好主意吗?谢谢,詹姆斯

编辑:这是时间序列数据,列是不同波长的测量值。数据需要在相对较窄的波长范围内进行分析。在未来的某个时候,也可能会添加额外的波长。

编辑:感谢大家的回答,我真的很感激:) 我想我可能会找时间用 500GB 左右的测试数据运行一些实验。我会带着任何结论回帖;)

database-design

18
推荐指数
3
解决办法
3330
查看次数

在 PostgreSQL 中查找表的空列

什么查询会返回所有行都为 NULL 的表的列名?

schema postgresql null database-design

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

类型字段的 INT 或 CHAR

表格或Type字段的最佳设计是什么?换句话说,鉴于此架构:intchar(1)

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehType .... not null
)
Run Code Online (Sandbox Code Playgroud)

VehType成为 anint或 a是否更有效(在性能方面)char(1)?假设你有五种类型的汽车,你应该使用递增值 0 -> 4,还是类型的字符(比如;'v'、's'、'c'、't'、'm')?

如果不止于此,我将使用单独的 Type 表并具有外键关系,但我认为没有必要这样做。

我注意到sys.objects目录视图为type字段使用了一个字符。有什么原因吗?我是否只是在稀薄的空气中抓住了它,这是我更舒服的吗?

database-design sql-server datatypes

18
推荐指数
1
解决办法
6041
查看次数

通过第三个数据库使用相同的登录名连接两个数据库是否更安全?

我们有以下设置:

  • 包含桌面软件使用的私有数据的多个生产数据库
  • 公共网站的网络数据库,需要来自私人数据库的一些数据
  • 一个中间数据库,其中包含一些从私有数据库中提取数据的视图和存储过程

目前网站登录web数据库,web数据库连接中间数据库,在生产数据库上拉取数据或执行存储过程。所有数据库都在同一个SQL实例上,整个过程使用同一个用户账号。

用户账户对web数据库和中间数据库有完全访问权限,但只能访问私有数据库的特定视图和存储过程

这真的比让公共数据库直接连接到私有数据库更安全吗?

中间数据库似乎只是为了使事情复杂化,因为使用相同的登录名访问所有数据库中的数据,并且它已经仅限于私有数据库中所需的视图/SP。我希望删除它。

security database-design

18
推荐指数
1
解决办法
438
查看次数

数据库设计:如何处理“归档”问题?

我很确定每天都有很多应用程序、关键应用程序、银行等等。

这一切背后的想法是:

  • 所有行都必须有历史记录
  • 所有链接必须保持连贯
  • 请求获取“当前”列应该很容易
  • 购买过时商品的客户仍然应该看到他们购买的商品,即使该产品不再是目录的一部分

等等。

这就是我想要做的,我将解释我面临的问题。

所有的表都会有这些列:

  • id
  • id_origin
  • date of creation
  • start date of validity
  • start end of validity

以下是 CRUD 操作的想法:

  • create = 用id_origin= id, date of creation=now, start date of validity=now, end date of validity=null插入新行(= 表示它是当前活动记录)
  • 更新 =
    • read = 用end date of validity==null读取所有记录
    • end date of validityend date of validity=now更新“当前”记录=null
    • 使用新值创建一个新的,并且end date of validity=null (= 表示它是当前活动记录)
  • 删除 =end …

database-design

18
推荐指数
1
解决办法
3484
查看次数

PostgreSQL 金融应用认证方式的选择

首先介绍一下背景。

LedgerSMB 项目是一个在 PostgreSQL 上运行的开源财务会计软件项目。我们在用户定义的函数中实现了大量的业务逻辑,它们充当程序对象方法和数据库行为之间的主要映射工具。目前我们使用数据库用户作为身份验证用户,部分是出于选择(这允许集中的安全逻辑,以便可以编写其他工具并重用授予用户的权限),部分是必要的(在我们从 SQL-Ledger 分叉之后,有用于在该代码库上改进安全性的选项并不多)。

这让我们可以访问 PostgreSQL 可以访问的合理数量的单点登录选项,从 LDAP 到 Kerberos 5。我们甚至可以在涉及密码的地方使用 PAM。它还允许我们在与其他应用程序集成或允许其他客户端界面时重用权限。对于财务会计应用程序来说,这似乎是一场胜利。

有明显的成本。对于 Web 应用程序,我们可以支持的 http 身份验证类型非常有限。例如,DIGEST 完全出局了。BASIC 可以工作,我们可以很容易地实现 KRB5(我计划支持它并在 1.4 中开箱即用)。非常强大的身份验证措施无法直接对此进行适当管理,尽管我们可能会在必要时将它们填充(例如 BASIC + 客户端 SSL 证书,其 cn 与用户名和特定的根 ca 匹配)。

与此同时,我们遇到了相当多的批评,主要来自开发人员,偶尔来自 dba 的批评,他们告诉我应用程序应该是安全屏障,而不是数据库。我的观点仍然是,较小的安全边界通常更好,业务逻辑和安全逻辑的重用是相辅相成的,我觉得重用业务逻辑而不在同一级别重用安全逻辑是危险的的程序。

我在这里错过了任何主要的权衡吗?有没有我没有考虑的问题?

postgresql security database-design

18
推荐指数
1
解决办法
3378
查看次数

了解通知系统

我一直在研究如何在 SE 和其他地方构建通知系统,并发现自己被这里接受的答案所吸引:https : //stackoverflow.com/questions/9735578/building-a-notification-system 使用这种结构:

???????????????      ?????????????????????      ??????????????????????
?notification ?      ?notification_object?      ?notification_change ?
???????????????      ?????????????????????      ??????????????????????
?ID           ?—1:n—??ID                 ?—1:n—??ID                  ?
?userID       ?      ?notificationID     ?      ?notificationObjectID?
???????????????      ?object             ?      ?verb                ?
                     ?????????????????????      ?actor               ?
                                                ??????????????????????
Run Code Online (Sandbox Code Playgroud)

通知是关于某事(对象 = 事件、友谊..)被某人(演员)更改(动词 = 添加、请求..)并报告给用户(主题)。这是一个规范化的数据结构(尽管我使用过 MongoDB)。您需要将更改通知某些用户。所以它是每个用户的通知......意味着如果有 100 个用户参与,你会生成 100 个通知。

起初我以为我理解这种方法,但是当我开始准备实施它时,我意识到我显然不是特别了解它。对答案的最后几条评论是其他用户在理解解决方案时遇到的问题。

我不确定这是否是我最终会遵循的模型,但考虑到它拥有的赞成票数量,我相信理解它会对我有益,而且我当然想了解更多。我希望这对在掌握此解决方案时遇到困难的其他人也有用(顺便说一句,我没有足够的互联网点来对针对此问题的答案发表评论,请其他人做!)

问题

如果我的理解对不对,notificationObjectID是一个外键指向notification_object表,notificationID是一个外键指向通知表。似乎object应该是一个外键,指的是通知所涉及的数据库条目的 ID(例如特定的事件或帖子),但是我们不需要另一个字段来指示该 ID 属于哪个表吗?

作者写道

Notification_object.object 标识更改类型,如字符串“friendship”。我所讨论的对已更改对象及其额外数据的实际引用在 notification_change.notificationObjectID 中

这对我来说似乎没有意义。Object 是一个字符串(枚举?),notificationObjectID 是一个外键,指的是通知所涉及的对象?那么中间和右边的桌子到底是怎么连接的呢?

中间的表格似乎指定了通知是关于什么对象(或对象类型),例如事件或帖子。然后我们可以在notification_change中有许多指向相同对象类型的条目,这允许我们捆绑通知(例如“25 个用户发布在 X 的墙上)——因此中间表和右表之间的 1:n …

database-design

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