当数据库的规模增长超过数百万行时,建议开始扩展应用程序,并将数据库分成多个物理服务器。
将数据库分割成多个部分的最大问题是,如果用户要求特定的数据,它的后续同步。
假设你有一个 "文章 "表,但由于你有一个巨大的网站,上面有数千万篇文章,你必须在多台机器上物理分割它们。
如果我们使用一个普通的整数作为`id'(主键),并设置为自动递增,我们会很快发现,当以分散的方式在不同的机器上创建记录,然后同步它们时,会出现ID碰撞,我们不得不以复杂的方式对记录重新编号。此外,如果我们要将许多会话解析到其他表中,这可能是一个非常复杂的开销,其中很容易出错。
因此,我们可以生成一个`UUID',而不是一个数字标识符,这是一个文本字符串,由一个复杂的算法生成,保证它是唯一的,即使它在多台机器上独立生成。
优势。
19010018
,很容易猜到用户19010017
和其他人也存在。这种攻击被称为矢量攻击。UUID既可以通过简单的SQL查询SELECT UUID();
获得,但这增加了对数据库的查询次数,而且我们失去了在应用逻辑中先批量准备数据,然后一次性写入的能力。
因此,我喜欢使用Composer获得的ramsey/uuid包作为一个好的解决方案。UUID本身有几个版本,软件包可以根据需要俏皮地生成各种版本。
这使得它易于使用。
require 'vendor/autoload.php';use Ramsey\Uuid\Uuid;// 生成版本1(基于时间)的UUID对象$uuid1 = Uuid::uuid1();echo $uuid1->toString() . "\n"; // e4eaaaf2-d142-11e1-b3e4-080027620cdd// 生成第3版(基于名字和MD5散列的)UUID对象$uuid3 = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net');echo $uuid3->toString() . "\n"; // 11a38b9a-b3da-360f-9353-a5a725514269// 生成第四版(随机)UUID对象$uuid4 = Uuid::uuid4();echo $uuid4->toString() . "\n"; // 25769c6c-d34d-4bfe-ba98-e0ee856f3e7a// 生成第5版(基于名字并以SHA1形式散列)UUID对象$uuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net');echo $uuid5->toString() . "\n"; // c4a760a8-dbcf-5254-a0d9-6a4474bd1b62
如果你使用Doctrine,有一个扩展ramsey/uuid-doctrine,可以直接生成ID,作为一种数据类型。
在我的第一次尝试中,我使用varchar(36)
作为主键(ID),但这根本不是一个好主意。
对内部逻辑的解释:
MySql数据库(和其他许多数据库)不能有效地使用
varchar
、char
或其他表达字符串的数据类型作为主键。 在一些数据库中,有一个GUID
数据类型,被设计用来直接存储UUID。如果你不能使用这种类型,有一个合适的替代品,形式为二进制(16)
。
当物理检查数据库时,ID会以HEX格式表示(因为二进制格式无法显示),而不是漂亮的ID726c67c4-e5eb-4a4c-8fcc-031da5d6f3c6
,你只会看到726C67C4E5EB4A4C8FCC031DA5D6F3C6
,看起来像INSERT查询中的`'?kYߟKg2c;'。
varchar(36)
转换为binary(16)
。我假设你在数据库中表示(或计划表示)新设置的ID为。
`id` binary(16) NOT NULL
然而,仅仅改变数据类型是行不通的,所以像这样的情况。
SET FOREIGN_KEY_CHECKS=0;ALTER TABLE article CHANGE id id BINARY(16) NOT NULLSET FOREIGN_KEY_CHECKS=1;
基本上有两个原因。
必须有相同的数据类型
。因此,你需要改变文章ID的数据类型,例如,在将文章与作者匹配的关系表中。因此,唯一正确的解决方案是备份数据(但无论如何,你应该在每次迁移之前做这件事),准备一个具有功能关系的空数据库,并通过迁移将数据再次放到那里。
如果你以前产生的UUID很奇怪,最好选择一些连续的方法来获得UUID,并对所有记录重新编号。原因是顺序布局允许更好地对值进行排序,并创建一个btree',这使得性能几乎与
bigint'相同。
如果你知道有什么更好的方法可以将现有的数据库从UUID存储为varchar格式转换为二进制格式,而不必设计复杂的迁移,并保留外键,我将非常感谢你的反馈。
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | zh