ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql-关系数据库(RDBMS)非规范化数据

2019-11-08 04:14:12  阅读:246  来源: 互联网

标签:database-design query-optimization relational-database mysql


我相信这个问题并没有专门针对MySQL-我正在使用的数据库-,而是关于最佳实践的问题.

到目前为止,我的问题可以通过创建表和查询表(有时在这里和那里联接)来解决.但是我正在做的事情感觉不对劲,每当我需要在我的“常见”查询旁边加上非规范化数据时,就会触发我.

示例用例

为了让我更好地表达自己,让我们创建一个肤浅的场景,其中:

>用户可以购买产品并产生购买(让我们忽略购买只能有一个产品这一事实);
>并且我们需要查询产品的购买总次数;

为了解决用例,我们可以定义一个简单的结构,该结构由:

>产品表:

> product_id [INT PK]

>用户表:

> user_id [INT PK]

>购买表:

> Purchase_id [INT PK]
> product_id [INT FK NOT NULL]
> user_id [INT FK不为空]

这是不对劲的地方:当我们需要检索具有购买总次数的产品列表时,我将创建查询:

# There are probably faster queries than this to reach the same output
SELECT
    product.product_id,
    (SELECT COUNT(*) FROM purchase
      WHERE purchase.product_id = product.product_id)
FROM
    product

我担心的原因是,我已经阅读到COUNT会进行全表扫描,并且当我缩放到要购买的数千种产品时,即使在购买时我已经用product_id FK创建了一个INDEX( MySQL默认执行此操作.

可能的解决方案

我对关系数据库的了解还很浅,因此在比较这些问题的替代方案(合理的替代方案)时,我有点迷失了.不用说我还没有做完作业(在询问之前先搜索),我发现可以这样做:

创建交易:

插入新购买商品时,它必须始终位于事务中,该事务还将使用purchase.product_id更新产品表.

可能的问题:人为错误.有人可能不进行交易和BAM而手动插入了购买商品-我们存在不一致之处.

创建触发器:

每当我插入,删除或更新某些特定表中的某些行时,我都会使用新值(bought_amount)更新我的产品表.因此表将变为:

>产品表:

> product_id [INT PK]
> buy_amount [INT NOT NULL];

可能的问题:触发器昂贵吗?有没有一种方法可以成功插入但触发器不会成功-从而使我前后不一致?

更新某些表以存储不断变化的数据是RDBMS的一种可行方法吗?长期加入并计数/求和其他事件是否更安全,并且从长远来看更有利?

我发现了一些有关此问题的有用问题/答案,但没有一个能广泛地解决这个问题.
请考虑我对RDBMS的无知,因为我可能会建议废话.

解决方法:

获取每个键计数的通常方法是

SELECT product_id, COUNT(*)
FROM purchase
GROUP BY product_id

您不需要提及产品表,因为它包含的只是键列.现在,尽管它使用COUNT(*),但是它不需要为每个product_id进行全表扫描,因为SQL引擎足够聪明,可以看到GROUP BY.

但这会产生与您的查询不同的结果:对于从未购买过的产品,我的查询根本不会显示它们;您的查询将显示带有零计数的product_id.

然后,在您开始担心实施和效率问题之前,您要尝试回答哪些问题?如果要查看是否购买了所有产品,则必须扫描整个产品表并从中查找要购买的产品.我会去

SELECT product_id, count
FROM product
OUTER JOIN (SELECT product_id, COUNT(*) AS count
            FROM purchase
            GROUP BY product_id) AS purch
ON product.product_id = purch.product_id

关于您的更广泛的问题(不确定我是否完全理解它们),在早期,SQL在这种连接和聚合方面效率很低,并且架构经常在多个表中使用重复的列进行非规范化. SQL引擎现在更加智能,因此没有必要.您可能会在较旧的教科书中看到这种过时的做法.我会忽略它,并设计您的架构尽可能规范化.

标签:database-design,query-optimization,relational-database,mysql
来源: https://codeday.me/bug/20191108/2005181.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有