我是SQL的新手,我不了解性能影响。似乎SQL数据库将所有内容存储在一个地方。这是不是意味着表变得非常大,非常快?这不会伤害表现吗?
示例Stackoverflow模型,但带有线程注释:
CREATE TABLE t_users (
name varchar(80) primary key,
email varchar(80)
);
CREATE TABLE t_posts (
id varchar(80) primary key,
userid varchar(80) references t_users(name),
title varchar(80),
description text,
topic varchar(80),
path text
);
这是一个有效的设计吗?每个用户的所有帖子都存储在同一个表中...因此,如果我想查询所有具有主题“编程”的评论,则需要查看每个帖子,即使是通过具有不同主题的帖子,它们都存储在同一个表中....这也意味着如果我制作更复杂的查询,它们将以指数方式增长得越慢,我的磁盘表越大。 将每个帖子分成新表不是更好吗?
答案 0 :(得分:3)
设计是准有效的,但不完全是:
t_users
最好是自动增量无符号
int ID列。 (名字上的主键几乎总是一个坏主意。人们改名。人们有相同的名字。甚至国家有时更改名称!数字几乎总是最好的选择!) t_posts
可以引用该userID。加入现在正在快速发展。t_posts
有一个ID主键列(好!),但它是varchar(坏!)。 INT更好。如果您需要,请BIGINT
。您稍后会发现您的帖子可能包含多个主题(stackoverflow“tags”)。不要将它们放在varchar字段中。使用ID,说明和链接表“posts_to_topic”创建一个新表“主题”,将每个帖子链接到一个或多个主题。
您需要阅读的是索引。如果要查询具有“编程”主题的所有注释,通常在“topic varchar(80)”列上有一个索引。这个索引很小(认为它是一个单独的表:它包含索引列和主键),因此您的(R)DBMS可以非常快速地搜索它(树结构)并获取它需要的所有主键。然后,根据您选择的内容,DBMS会向您发送信息:
但首先阅读关于索引的内容,关于什么,原因以及后来的方法。之后,您可以更深入地研究异常。
这是一个经常犯的初学者错误,它们都是双向的:
阅读索引将告诉你为什么这在技术上是一个坏主意,但它在逻辑尺度上也不那么优雅:一个表意味着代表一个实体(书籍。用户。帖子。页面) - 拆分这些将导致一些非常难看的问题。如果你问某人他们为什么这样做,原因往往是“为了速度”,而他们的决策栏上的额外索引会产生同样的效果。
考虑一下:如果您为每个用户创建帖子标题,请编写列出10个最常用主题的查询,以及每个主题的帖子数量。你必须为每张桌子命名!
答案 1 :(得分:3)
问题的真正答案前两个问题是“是”和“否”。 “是”,表格确实快速增长。而“不”这通常不会影响表现。
虽然您可以将表视为单个文件来扫描以查找结果,但SQL所做的远不止这些。几乎所有数据库都管理称为页表的内容,这意味着以下内容:
这两点本身在大多数编程语言中实现起来非常困难(但并非不可能)。此外,SQL为您提供了索引和表分区,可以进一步加快单个表的处理速度。最后,大多数SQL版本几乎支持所有功能的多个处理器/线程。
当涉及组合来自多个表的结果或聚合结果时,数据库在用于进行连接和聚合的算法中有许多人年的努力。在这种情况下你不太可能做得更好。
并且,这些功能不涉及关系数据库的许多其他功能,例如强制数据的一致性,备份和恢复数据,保证修改等。
至于你的表架构,似乎你已经开始了,它很好。一般来说,我建议您的主键以表格命名并为整数。你的第一张表就是:
CREATE TABLE users (
UserId int primary key,
name varchar(80),
email varchar(80)
);
第二个表中的UserId被声明为int。作为为何更好的提示,用户可能希望不时更改其名称。
答案 2 :(得分:1)
将每个帖子拆分成新表会不会更好?
没有
如果你的帖子在不同的表中,那么你必须查询数百甚至数千个不同的表来查找所有数据。
更不用说,除了数据(大小相同,无论它在哪个表中),你都有表格本身的开销。