删除重复数据
DROP TABLE IF EXISTS contacts_test;
CREATE TABLE contacts_test (
id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(255) NOT NULL
);
INSERT INTO contacts_test (first_name,last_name,email)
VALUES ('Carine ','Schmitt','carine.schmitt@verizon.net'),
('Jean','King','jean.king@me.com'),
('Peter','Ferguson','peter.ferguson@google.com'),
('Janine ','Labrune','janine.labrune@aol.com'),
('Jonas ','Bergulfsen','jonas.bergulfsen@mac.com'),
('Janine ','Labrune','janine.labrune@aol.com'),
('Susan','Nelson','susan.nelson@comcast.net'),
('Zbyszek ','Piestrzeniewicz','zbyszek.piestrzeniewicz@att.net'),
('Roland','Keitel','roland.keitel@yahoo.com'),
('Julie','Murphy','julie.murphy@yahoo.com'),
('Kwai','Lee','kwai.lee@google.com'),
('Jean','King','jean.king@me.com'),
('Susan','Nelson','susan.nelson@comcast.net'),
('Roland','Keitel','roland.keitel@yahoo.com');
以下查询返回表中的重复电子邮件contacts_test:
SELECT
email, COUNT(email)
FROM
contacts_test
GROUP BY
email
HAVING
COUNT(email) > 1;
使用DELETE JOIN语句删除重复的行
DELETE t1 FROM contacts_test t1
INNER JOIN
contacts_test t2
WHERE
t1.id < t2.id AND t1.email = t2.email;
id为2,4,7和9的行已被删除。
如果要删除重复行并保留最低ID,可以使用以下语句:
DELETE t1 FROM contacts_test t1
INNER JOIN
contacts_test t2
WHERE
t1.id > t2.id AND t1.email = t2.email;
使用中间表删除重复的行
- 创建一个新表,其结构与要删除重复行的原始表相同。
- 将原始表中的不同行插入到直接表中。
- 删除原始表和重命名立即表的原始表。
步骤1。
CREATE TABLE source_copy LIKE source;
第2步。
INSERT INTO source_copy
SELECT * FROM source
GROUP BY col; -- col 是有重复数据的列
第3步。
DROP TABLE source;
ALTER TABLE source_copy RENAME TO source;
以下语句从contacts_test表中删除包含重复电子邮件的行:
-- step 1
CREATE TABLE contacts_temp
LIKE contacts_test;
-- step 2
INSERT INTO contacts_temp
SELECT *
FROM contacts_test
GROUP BY email,id;
-- step 3
DROP TABLE contacts_test;
ALTER TABLE contacts_temp
RENAME TO contacts_test;
使用ROW_NUMBER() 函数删除重复的行
请注意,ROW_NUMBER()自MySQL版本8.02起,功能已得到支持,因此您应在使用功能之前检查您的MySQL版本。
以下语句使用ROW_NUMBER()函数为每行分配一个顺序整数。如果电子邮件重复,则行号将大于1。
SELECT
id,
email,
ROW_NUMBER() OVER (
PARTITION BY email
ORDER BY email) AS row_num
FROM
contacts_test
以下语句返回重复行的id列表:
SELECT
id
FROM (
SELECT
id,
ROW_NUMBER() OVER (
PARTITION BY email
ORDER BY email) AS row_num
FROM
contacts_test
) t
WHERE
row_num > 1;
删除从重复的行contacts使用表DELETE与语句子查询 中的WHERE
DELETE FROM contacts_test
WHERE id IN (
SELECT id
FROM (
SELECT id, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY email) AS row_num
FROM contacts_test
) t
WHERE row_num > 1
);
UUID
UUID代表Universally Unique IDentifier。UUID基于RFC 4122 “通用唯一标识符(UUID)URN命名空间”定义。
UUID被设计为在空间和时间上全球唯一的数字。预计两个UUID值是不同的,即使它们是在两个独立的服务器上生成的。
在MySQL中,UUID值是一个128位数字,表示为五个十六进制数字的utf8字符串,格式如下:
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
要生成UUID值,请使用以下UUID()函数:
select UUID();
MySQL UUID与INT自增作为主键比较
将UUID用作主键 具有以下优点:
- 表,数据库甚至服务器之间的UUID值是唯一的,它们允许您合并来自不同数据库的行或跨服务器分发数据库。
- UUID值不会公开有关数据的信息,因此在URL中使用它们更安全。例如,如果ID为10的客户通过http://www.example.com/customers/10/URL 访问其帐户,则很容易猜到有客户11,12等,这可能是攻击的目标。
- 可以在避免往返数据库服务器的任何地方生成UUID值。它还简化了应用程序中的逻辑。例如,要将数据插入父表和子表,您必须先插入父表,获取生成的ID,然后将数据插入子表。通过使用UUID,您可以预先生成父表的主键值,并在事务中同时将行插入父表和子表。
除了优点,UUID值也有一些缺点:
- 存储UUID值(16字节)比整数(4字节)或甚至大整数(8字节)占用更多存储空间。
- 调试似乎更难,想象一下表达WHERE id = ‘df3b7cb7-6a95-11e7-8846-b05adad3f0ae’ 而不是WHERE id = 10
- 使用UUID值可能会导致性能问题,因为它们的大小和没有被排序。
MySQL UUID解决方案
在MySQL中,您可以使用紧凑格式(BINARY)存储UUID值,并使用以下函数以人类可读的格式(VARCHAR) 显示它们:
- UUID_TO_BIN
- BIN_TO_UUID
- IS_UUID
请注意UUID_TO_BIN(),BIN_TO_UUID()和IS_UUID()功能仅在MySQL 8.0或更高版本可用。
UUID_TO_BIN() 函数将UUID从人类可读格式(VARCHAR)转换为紧凑格式(BINARY)格式用于存储,并且BIN_TO_UUID()函数将UUID从紧凑格式(BINARY)转换为人类可读格式(VARCHAR)以进行显示。
IS_UUID()如果参数是有效的字符串格式UUID,则函数返回1。如果参数不是有效的字符串格式UUID,则IS_UUID函数返回0.如果参数为NULL,则 IS_UUID()函数返回NULL。
以下是MySQL中有效的字符串格式UUID:
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
aaaaaaaabbbbccccddddeeeeeeeeeeee
{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}
示例:
CREATE TABLE people (
id BINARY(16) PRIMARY KEY,
name VARCHAR(255)
);
INSERT INTO people(id, name)
VALUES(UUID_TO_BIN(UUID()),'John Doe'),
(UUID_TO_BIN(UUID()),'Will Smith'),
(UUID_TO_BIN(UUID()),'Mary Jane');
SELECT
BIN_TO_UUID(id) id,
name
FROM
people;
表的存储引擎
查询表的当前存储引擎
-- 第一种方法是从information_schema数据库中的表中查询数据。
SELECT
engine
FROM
information_schema.tables
WHERE
table_schema = 'mysqldemo'
AND table_name = 'offices';
-- 第二种方法是使用SHOW TABLE STATUS如下语句:
SHOW TABLE STATUS LIKE 'offices';
-- 第三种方法是使用SHOW CREATE TABLE语句。
SHOW CREATE TABLE offices;
MySQL改变存储引擎
获得表的存储引擎信息后,可以使用ALTER TABLE语句更改它,如下所示:
ALTER TABLE table_name ENGINE engine_name;
要检查MySQL服务器当前支持的存储引擎,请使用SHOW ENGINES语句,如下所示:
SHOW ENGINES;