标签: physical-design

多租户 SQL Server 数据库中的复合主键

我正在使用 ASP Web API、实体框架和 SQL Server/Azure 数据库构建多租户应用程序(单一数据库、单一架构)。此应用程序将被 1000-5000 名客户使用。所有的表都会有TenantId(Guid / UNIQUEIDENTIFIER) 字段。现在,我使用单字段主键,即 Id (Guid)。但是通过仅使用 Id 字段,我必须检查用户提供的数据是否来自/用于正确的租户。例如,我有一个SalesOrder包含CustomerId字段的表。每次用户发布/更新销售订单时,我都必须检查它CustomerId是否来自同一个租户。情况变得更糟,因为每个租户可能有多个网点。然后我必须检查TenantIdOutletId。这真的是一个维护噩梦,对性能不利。

我想添加TenantId主键沿Id。也可能添加OutletId。所以SalesOrder表中的主键将是:IdTenantId、 和OutletId。这种方法的缺点是什么?使用复合键会严重影响性能吗?复合键顺序重要吗?我的问题有更好的解决方案吗?

index sql-server physical-design multi-tenant design-pattern

20
推荐指数
1
解决办法
5077
查看次数

从表中获取最后一行的最快方法是什么?

我有一个 PostgreSQL 表Prices,包含以下列:

  • price (十进制)
  • product_id (国际)

还有created_atupdated_at列。

价格会定期更新,我会在表中保留旧价格。对于给定的产品,表中的最后一个价格是当前价格。

获得特定产品最后价格的最有效方法是什么:

  • 索引product_id和查询最后一条记录
  • 添加第三列active(布尔值)以标记最新价格并创建复合索引(product_idactive
  • 或者是其他东西?

postgresql physical-design

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

PostgreSQL 如何对磁盘上的新记录进行物理排序(在主键上的集群之后)?

需要知道 PostgreSQL 如何在磁盘上订购记录。在这种情况下,我想利用文档中所述索引组合,据我所知,它使用位图来获取匹配的行并根据它们的物理位置返回它们。有问题的表已按其主键聚集在一起。

据我了解,在集群完成后,PostgreSQL 不会自动继续进行集群(尽管它确实记得它是根据某个索引进行集群的)。现在,由于这是主键,我想知道物理存储顺序是否会根据它(如果是真的,我想利用我们的优势来进行特定查询)。

综上所述,PostgreSQL 如何对其新记录进行排序,尤其是在聚类之后?

非常感谢!

postgresql index database-design clustered-index physical-design

9
推荐指数
1
解决办法
2292
查看次数

为charindex函数拆分/存储长字符串的最快方法

我有一个 1 TB 的数字串。给定一个 12 个字符的数字序列,我想获取该序列在原始字符串(charindex函数)中的起始位置。

我已经使用 SQL Server 使用 1GB 字符串和 9 位子字符串对此进行了测试,并将字符串存储为varchar(max). Charindex需要 10 秒。将 1GB 字符串分解为 900 字节重叠块并创建一个表(StartPositionOfChunk、Chunkofstring),其中包含二进制排序规则的 chunkofstring,索引时间不到 1 秒。10GB,10 位子字符串的后一种方法将 charindex 提高到 1.5 分钟。我想找到一种更快的存储方法。

例子

数字串:0123456789 - 要搜索的子字符串 345
charindex('345','0123456789') 给出 4

方法 1:我现在可以将其存储在包含一列的 SQL Server 表 strtable 中colstr并执行:

select charindex('345',colstr) from strtable
Run Code Online (Sandbox Code Playgroud)

方法2:或者我可以通过拆分原始字符串来组成一个表strtable2(pos,colstr1)1;012 | 2;123 | 3;234 aso然后我们可以进行查询

select pos from strtable2 where colstr1='345'
Run Code Online (Sandbox Code Playgroud)

方法 3:我可以通过将原始字符串拆分成更大的块来组成一个表strtable2 (pos2,colstr2) …

sql-server physical-design string-splitting sql-server-2017 string-searching

8
推荐指数
2
解决办法
839
查看次数

宽聚集索引与多个窄非聚集索引?

假设我有一个Student像这样的人为表:

CREATE TABLE Student (
    Id IDENTITY INT,
    SchoolId INT NOT NULL,
    FirstName VARCHAR(20) NOT NULL,
    LastName VARCHAR(20) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

本能地,我会制作Id主键(以及聚集索引)。但是,我会发现自己在搜索,SchoolId因此我会在SchoolId.

这与主键(和聚集索引)相比如何SchoolId, Id?我将始终拥有SchoolIdif 我需要搜索 by Id,所以无论如何我都会使用聚集索引,如果我只需要搜索 by SchoolId,记录将在物理上彼此相邻。

如果我要进行任何类型的搜索或批量更新,它们会在SchoolId特定记录上,例如找到所有带有姓名/号码/任何内容的孩子SchoolId。我永远不会SchoolId在同一事务中跨多个s执行这些类型的操作。让这些记录在物理上彼此相邻的好处是否使这种方法比简单地在 上使用聚集索引要好得多Id

使用后者有很大的缺点吗?我还是个新手,有很多主题我还没有完全理解(例如碎片化)以及它如何影响这种情况。

sql-server clustered-index index-tuning physical-design nonclustered-index

6
推荐指数
1
解决办法
835
查看次数

插入和更新的单独存储过程?

我在 Microsoft SQL Server 中有一个表。有时需要更新,有时需要插入。我可以写2个存储过程:

InsertNewPerson
UpdatePertsonById
Run Code Online (Sandbox Code Playgroud)

但我正在考虑编写 1 个存储过程而不是 ( SetPerson),这两个过程都可以(如果有ID,则是update操作,否则insert)。

我应该创建一个存储过程(只需要维护一个)还是应该创建两个不同的存储过程?

sql-server-2008 sql-server stored-procedures physical-design upsert

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

在 docker 容器中运行数据库服务器集群有意义吗?

我目前正在考虑建立一个数据库集群(MySQL Galera 或 Percona),但我只有 2 台机器。

但是,根据我读过的许多来源(这篇来自 Mariadb KB 的文章),集群中的最小节点大小应为 3,以避免出现裂脑情况。

为了避免裂脑情况,集群中推荐的最小节点数为3。阻止状态转移是需要至少3 个节点才能在其中一个成员发生故障并需要重新启动时享受服务可用性的另一个原因。虽然其中两名成员将从事状态转移,但其余成员将能够继续为客户请求提供服务。

所以我想知道我是否可以在两台机器上运行 3 个(或更多)docker 容器,每个容器都运行一个数据库服务器。如果其中一台机器出现故障,集群中仍然有 3 个节点,因此不会出现裂脑问题。

感觉像是作弊,但我想不出不这样做的理由。

这个设置有意义吗?

mysql clustering physical-design xtradb-cluster galera

5
推荐指数
1
解决办法
3568
查看次数

表定期大量增长和收缩的分配策略

我有一个 SQL Server 2014 数据库,其中包含 100 多个表,在一年中的增长率为 5%。读书多,写作少。

该数据库将通过另一组 20 多个表进行扩展,这些表定期(每季度)在一夜之间增长,几乎与整个数据库其余部分的总和一样多。

这些表在处理结束时在几个小时内完全清空。该数据这些表是相当消耗,但需要在同一个数据库,其余为参照完整性。

对于一些示例数字,假设第一个 DB 是 20GB,表的子集增长到 15GB,然后被清空。因此,数据的实际大小在几天内在 20 到 35 GB 之间波动。

  • 在规划这个系统时我可以做些什么来帮助解释这种波动?
  • 这是文件组发挥作用的地方吗?
  • 我将这组表移动到它们自己的文件组有什么优势/问题?

sql-server filegroups scalability physical-design sql-server-2014

5
推荐指数
1
解决办法
61
查看次数

您能否在不更改 SQL 模块或表定义的情况下获得分区消除的性能优势?

我为一家拥有当前不使用数据库分区的多租户数据库模型的公司工作。理想的最终状态是向每个现有表添加一个新的 TenantID 列,包括这个新列作为每个主键中的第一列,并重写所有现有的 SQL 定义以过滤和对 TenantID 进行等联接。

然而,由于现有的 SQL 模块数以千计,这是一个资源密集型解决方案,完全重写整个数据库。所以我的新计划是分阶段进行此更新。

第一阶段将完全保持现有的数据库模式,并创建对齐的数据库分区,这些分区使用现有的供应商 ID 列(几乎在每个表中)作为 TenantID 的代理。供应商 ID 已经很好地符合我想用租户 ID 做的事情。现有供应商聚集成供应商组,因此可以将一组供应商视为单个租户。

所以我的问题是。如果我这样做,在现有表上创建对齐的数据库分区而不更改任何表架构或任何现有 SQL 模块的定义,我会看到任何性能优势吗?

您可以在评论中询问更多信息,我会更新问题以反映它们。但是对于初学者来说,有许多现有的查询会根据供应商 ID 进行过滤,但很少有与之匹配的查询。

performance sql-server partitioning physical-design query-performance

5
推荐指数
1
解决办法
221
查看次数

一张大桌子 vs 几张小桌子

请注意,下面的示例只是一个示例,我的场景要复杂得多,而且我尝试对其进行建模的方式确实很有意义

假设我正在我的一个应用程序中为审计事件创建一个表 - 所以所有的“event_created”、“user_created”等等。该表包含几列,其中一些是其他表的外键。随着时间的推移,这个单个表可以增长到数百万条记录。

从性能的角度来看,对所有这些事件使用单个表还是对每种事件使用单独的表并在单独的表上操作是更快、更高效?还是差别不大?为每种事件创建一个单独的表可能听起来很愚蠢,但您需要相信我,在我的现实世界场景中,这真的很有意义。

postgresql database-design physical-design

5
推荐指数
1
解决办法
3271
查看次数