关于数据库性能的快速问题。我将在下面概述我的网站目的作为背景。
我正在创建一个字典网站,用于将用户定义的字词保存到数据库中。我想知道的是,是否为每个用户创建一个单词表或保留一个庞大的单词表。这个网站将用于整个学校,所以单个单词表将是巨大的!
数据库结构如下:
用户表格:
和一个单词表:
所以我要问的是,性能方面,我应该为每个用户在加入网站时创建一个新表 - 每个用户可能会随着时间的推移有数百或数千个单词?或者更好的是拥有一个包含成千上万条记录的大型表,并按User_ID进行过滤。我认为我不会执行很多表连接。
我的直觉是为每个用户创建一个新表,但我想我会请求专家建议!提前谢谢。
答案 0 :(得分:2)
我认为你应该为所有用户和user_id使用一个表。
任何语言都没有那么多单词。通过这么多,我了解了几百万。数据库工作正常,有1-2百万条记录,考虑到英语中的所有单词数超过170.000
,您很快就达不到这个水平答案 1 :(得分:1)
对于非常大的数据集,您可以通过将字典单词存储在每个用户的单独表中来获得更好的性能。
但是,如果您想针对所有单词运行查询,例如,对于统计分析,编写查询以访问每个人的单词将会很困难。
您可以将所有单词存储在同一个表中,然后如果性能出现问题,您可以随时对表进行分区,对用户ID进行散列。查找MySQL的“分区”。它基本上将数据存储在单独的文件中,但允许您将所有数据保存在同一逻辑表中,因此仍然可以轻松查询并保持正常形式。
只要您对user_id上的字词编制索引,性能就不会在相当长的一段时间内降低,并且您的应用程序可能永远不会达到该阈值。
从开发的角度来看,通过保持简单并将所有单词存储在同一个表中,您将节省数小时的时间。由于您有未来的解决方法,如果出现性能问题,请保持简单,并以最小的努力完成项目。
答案 2 :(得分:0)
表现方面,依赖指数。如果某些列的前缀是索引的键,则index通常可用于获取行而不扫描表。有些查询不会使用索引(例如,如果列只出现在某些branches of an AND
中),但这些查询不包括仅为给定用户查找单词;另外,对于每个用户来说,这些查询会更加困难。
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32) UNIQUE,
first VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
last VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
...
) Engine=InnoDB;
-- table of english words
CREATE TABLE vocabulary (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
word VARCHAR(45),
...
-- searches for words of a given user should use `user_word`
UNIQUE INDEX user_word (user_id, word),
INDEX (word),
FOREIGN KEY user (user_id) REFERENCES users (id)
ON DELETE CASCADE ON UPDATE CASCADE
) Engine=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
我们可以有first
,last
和surname
列,而不是given_name
和middle_names
列,因为不是每个文化都会given name first }。当然,我们需要记录要打印的名称的顺序。另一种选择是为full name和给定名称添加列。
word
列是45个字符,以允许英语中最长的单词,构造的单词“pneumonoultramicroscopicsilicovolcanoconiosis”。对于德语单词,我们至少需要63个字符。实际上使用了“Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz”,而不仅仅是尝试最长的单词。考虑到德语的本质,试图找到最长的单词长度是徒劳的。最好随意挑选一个。密钥大小上的limits(MySQL 5.0.17及更高版本中的3072字节,MySQL 5.0.15及更早版本中的1023字节)在{{1}的大小上设置了3066(1018 in 5.0.15)字节的上限},这是latin1_german1_ci(字典整理)中的3066(1018)个字符和UTF-8中的1022(339)个字符。