我正在使用 ASP Web API、实体框架和 SQL Server/Azure 数据库构建多租户应用程序(单一数据库、单一架构)。此应用程序将被 1000-5000 名客户使用。所有的表都会有TenantId
(Guid / UNIQUEIDENTIFIER
) 字段。现在,我使用单字段主键,即 Id (Guid)。但是通过仅使用 Id 字段,我必须检查用户提供的数据是否来自/用于正确的租户。例如,我有一个SalesOrder
包含CustomerId
字段的表。每次用户发布/更新销售订单时,我都必须检查它CustomerId
是否来自同一个租户。情况变得更糟,因为每个租户可能有多个网点。然后我必须检查TenantId
和OutletId
。这真的是一个维护噩梦,对性能不利。
我想添加TenantId
主键沿Id
。也可能添加OutletId
。所以SalesOrder
表中的主键将是:Id
、TenantId
、 和OutletId
。这种方法的缺点是什么?使用复合键会严重影响性能吗?复合键顺序重要吗?我的问题有更好的解决方案吗?
index sql-server physical-design multi-tenant design-pattern
我有3张桌子:
当我设计 ER 模型时,它具有循环依赖关系:
1:N 人 --------< 帖子 1:N 发帖 ----------< 点赞 1:N 人们 --------< 喜欢
逻辑是:
1个人可以有很多帖子。
1个帖子有很多赞。
1个人可以点赞多个帖子(创建的人不能点赞自己的帖子)。
我怎样才能消除这种循环设计?还是我的数据库设计错了?
我想了解敏捷软件开发方法/原则/模式是否也适用于 SQL 编程。如果是,从哪里开始学习这个的好地方?是否有针对 SQL 上下文中的敏捷开发的文章或书籍?
在以下场景中寻找与优化设计相关的一些建议。
选项A:
一张表有 2 个外键列,其中将填充一个且仅一个外键。
表:库存需求
在这种情况下,CaseId 或 LocationInventoryId 将为 null,而另一个已填充。
选项B:
每种需求类型有两个表,经常通过 UNION 来获取摘要数据。
表:库存需求案例
表:库存需求地点
选项C:
一张没有参照完整性的表。
表:库存需求案例
最终获胜者是?我可能会将范围缩小为 A 或 B 以确保数据完整性......但不确定哪个是最好的。或者也许有一个选项 D(例如创建具有公共列的基表......)
更新的场景
当我昨晚发布此内容时,我只考虑下游,但也存在对这些相同表的上游依赖关系。我画了一些图,希望能更好地解释它。随着这个出现,选项 B 开始爆炸所涉及的表的数量,在阅读了这个 SE 答案之后……我现在更倾向于 A。
下面的图片。然后红色代表库存需求,绿色代表满足这些需求的库存来源。黄色是当前的问题......如何有效地连接红色和绿色。
我每天有 2 种类型的表来填充数据仓库,查找表或配置表只有 100 条记录,这很容易,我只需截断和重新填充表。
但是对于有很多记录的事务表,我通常会递增,即我每天运行 ETL 以添加昨天的记录。
我有两个我总是面临的问题
现在我正在尝试设计一种方法来解决这两个问题,并尝试以这样一种方式开发 ETL,以便在发生任何这些事件时它可以自动修复它。
我希望它检查是否缺少天数并运行该天的 ETL,并检查是否有重复项并删除它们。
以下是我认为的方法 1. 我在过去 5 天里不管,ETL 运行的每一天,删除过去 5 天并重新填充。2.我检查目标表是否在上个月缺少日期,然后我用缺少的天数查询源。
请记住,源是生产环境中的一个巨大表,我必须在从它请求时最大限度地优化我的查询。
谢谢
这是我在这里的第一篇文章,所以我希望它足够清楚。我想为销售、购买、出租和修理某种产品的人制作一个应用程序。
我需要创建一个数据库来保存产品和帐户的数据(包括登录名和个人信息)。我的问题是,“帐户”可以是卖方、买方、承租人、修理工,可以是全部、无或某些。卖家、买家、租房者和修理者会有不同的领域,就像卖家可以发布产品,并保存一些只有卖家才能拥有的信息,修理者只能发布他的列表,但卖家,也可以是固定器。买家也可以出售产品并喜欢其他人。卖家和买家之间的区别在于卖家必须是一家公司,等等……
我对数据库的想法是这样的:
产品
product_id
product_name
owner_id (account_id)
Run Code Online (Sandbox Code Playgroud)
帐户
account_id
email
password
Run Code Online (Sandbox Code Playgroud)
卖方
seller_id
account_id
business_name
address
[some fields that only sellers would have...]
Run Code Online (Sandbox Code Playgroud)
买方
buyer_id
account_id
first_name
last_name
address
[some fields that only buyer would have...]
Run Code Online (Sandbox Code Playgroud)
承租人
renter_id
account_id
business_name
address
[some fields that only renter would have...]
Run Code Online (Sandbox Code Playgroud)
固定器
fixer_id
account_id
business_name
address
years_experience
[some fields that only fixers would have...]
Run Code Online (Sandbox Code Playgroud)
然后是其他表,如 account_favorite(用于保存有关哪些产品已被选为收藏的信息)。
现在,我觉得我这样做的方式不是正确的方式。还想如果将来我考虑其他事情,例如“收集器”,我将不得不创建一个新表。因为这是一个会被很多人使用的应用程序,所以我必须关心速度,但我也必须关心人们维护和分析数据。我希望这篇文章很清楚,如果不清楚,请问我。
以下数据库架构设计/模式是否有名称?我的最终目标是找到更多关于该主题的文献。今天的粗略网络搜索太多通用词,无法确定此类事物的术语(如果存在):
Fruit (id, farm)
Apple (fruit_id, color)
[fruit_id => Fruit.id]
Banana (fruit_id, length)
[fruit_id => Fruit.id]
Orange (fruit_id, is_seedless)
[fruit_id => Fruit.id]
FruitPack (id, destination)
FruitPackFruits (fruitpack_id, fruit_id, fruit_type)
[fruit_id => Fruit.id, fruit_type => VARCHAR]
Run Code Online (Sandbox Code Playgroud)
其中fruit_type将是一个varchar 列,其中填充了诸如“Apple、Banana、Orange、Cherry”之类的值。这是某种“穷人的参照完整性”。显然,这种设计的失败之一是能够插入无法解析为有用连接的值(即:这里没有樱桃可言)。
这是此类模式的另一个示例:单个“日志(id、table_name、record_id、timestamp)”表充当各种其他表中修改时间的跟踪器。严格来说,它没有 ref 完整性,但是, (table_name, record_id) 部分应该引用另一个表中的某些记录,需要连接才能实际获取完整数据。
我将理所当然地认为模式是这里人们的某种项目组集合的充分讽刺。
问题是:这种“穷人的参照完整性”叫什么?
我不是想了解参照完整性。我想确定这个糟糕设计的名称,并进一步研究与这种常见的模式灾难有关的“让我们设计一个数据库模式”方面(例如:优点、缺点、意见、教导等)。
DECLARE @key INTEGER = 33, @val INTEGER = 44;
BEGIN TRANSACTION;
INSERT dbo.t([key], val)
SELECT @key, @val
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.t WITH (UPDLOCK, SERIALIZABLE)
WHERE [key] = @key
);
IF @@ROWCOUNT = 0
BEGIN
UPDATE dbo.t SET val = @val WHERE [key] = @key;
END
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
DECLARE @key INTEGER = 33, @val INTEGER = 44;
BEGIN TRANSACTION;
INSERT dbo.t WITH (UPDLOCK, SERIALIZABLE) ([key], val)
SELECT @key, @val
WHERE NOT EXISTS
(
SELECT 1 …
Run Code Online (Sandbox Code Playgroud) 我有 post_order 列的帖子表。我将每个帖子的顺序存储在其中。当我将一行的顺序从 25 更改为 15 时,我应该将所有行从 15 更新到结尾。它适用于几行,但在数千行中最糟糕。
有没有更好的订购帖子的设计,更有效?
design-pattern ×10
sql-server ×4
mysql ×2
postgresql ×2
development ×1
etl ×1
hints ×1
index ×1
learning ×1
multi-tenant ×1
ssis ×1
unit-test ×1
upsert ×1