上一章: 【MySQL】数据库基础 ②
说明:
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
临时表在MySQL 3.23版本中添加,如果你的MySQL版本低于 3.23版本就无法使用MySQL的临时表。
如果你使用了其他MySQL客户端程序连接MySQL数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然你也可以手动销毁
CREATE TEMPORARY TABLE product_temporary (
product_name VARCHAR(50) NOT NULL,
total_sales DECIMAL(10,2) NOT NULL DEFAULT 0.00,
price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
sold_total INT UNSIGNED NOT NULL DEFAULT 0
);
INSERT INTO product_temporary (product_name, total_sales, price, sold_total) VALUES ('手机', 100.25, 90, 2);
select * from product_temporary;
当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 product_temporary 表。
如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了。
说明:
默认情况下,当你断开与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前MySQL会话使用 DROP TABLE 命令来手动删除临时表。
手动删除临时表
DROP TABLE product_temporary;
说明:
如果我们需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等。 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的。
如何完整的复制MySQL数据表,步骤如下:
SHOW CREATE TABLE text_table \G;
*************************** 1. row ***************************
Table: text_table
Create Table: CREATE TABLE `text_table` (
`text_id` int unsigned NOT NULL AUTO_INCREMENT,
`text_title` varchar(100) NOT NULL,
`text_author` varchar(40) NOT NULL,
`submission_date` date DEFAULT NULL,
PRIMARY KEY (`text_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)
CREATE TABLE `text_copy` (
`text_id` int unsigned NOT NULL AUTO_INCREMENT,
`text_title` varchar(100) NOT NULL,
`text_author` varchar(40) NOT NULL,
`submission_date` date DEFAULT NULL,
PRIMARY KEY (`text_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb3;
INSERT INTO text_copy (text_id,text_title,text_author,submission_date)
SELECT text_id,text_title,text_author,submission_date FROM text_table;
执行以上步骤后,会完整的复制表的内容,包括表结构及表数据。
mysql> select * from text_copy;
+---------+----------------+--------------+-----------------+
| text_id | text_title | text_author | submission_date |
+---------+----------------+--------------+-----------------+
| 1 | 安徒生童话 | 臭弟弟 | 2023-06-16 |
| 2 | 小天鹅与丑小鸭 | 你才是臭弟弟 | 2023-06-16 |
| 3 | 西游记 | 我不是臭弟弟 | 2023-06-16 |
| 5 | csdn | 作者 | 2023-06-19 |
| 6 | 测试 | text | 2023-06-19 |
+---------+----------------+--------------+-----------------+
5 rows in set (0.29 sec)
说明:
MySQL元数据(Metadata)是指MySQL数据库中关于数据结构的信息,如数据库、表、列、索引等信息。在MySQL中,元数据通常以数据字典的形式存储在系统数据库中,可以通过查询数据字典来获取元数据信息。
SHOW DATABASES;
SHOW TABLES;
DESCRIBE table_name;
SHOW INDEX FROM table_name;
SHOW TABLE STATUS LIKE 'table_name';
SELECT user, host, grant_priv, super_priv FROM mysql.user;
SELECT * FROM information_schema.USER_PRIVILEGES;
SHOW TABLE STATUS;
命令 | 描述 |
---|---|
SELECT VERSION() | 服务器版本信息 |
SELECT DATABASE() | 当前数据库名 (或者返回空) |
SELECT USER() | 当前用户名 |
SHOW STATUS | 服务器状态 |
SHOW VARIABLES | 服务器配置变量 |
说明:
数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。
主要介绍如何防止数据表出现重复数据及如何删除数据表中的重复数据。
实例:下表中无索引及主键,所以该表允许出现多条重复记录。
CREATE TABLE person_table
(
first_name CHAR(20),
last_name CHAR(20),
sex CHAR(10)
);
如下所示:
CREATE TABLE person_table
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
PRIMARY KEY (last_name, first_name)
);
补充:
当然使用可视化工具 更方便效率更高,如下图
以下实例使用了 INSERT IGNORE INTO,执行后不会出错,也不会向数据表中插入重复数据:
mysql> INSERT IGNORE INTO person_table (last_name, first_name)VALUES( 'mr.xiao', 'csdn');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> INSERT IGNORE INTO person_table (last_name, first_name)VALUES( 'mr.xiao', 'csdn');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select * from person_table;
+------------+-----------+------+
| first_name | last_name | sex |
+------------+-----------+------+
| Thomas | Jay | NULL |
| csdn | mr.xiao | NULL |
+------------+-----------+------+
2 rows in set (0.00 sec)
另一种设置数据的唯一性方法是添加一个 UNIQUE 索引,如下所示:
CREATE TABLE person_table
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
UNIQUE (last_name, first_name)
);
SELECT
COUNT(*) AS repetitions,
last_name,
first_name
FROM
person_table
GROUP BY
last_name,
first_name
HAVING
repetitions > 1;
以上SQL查询在person_table表中具有重复值的last_name和first_name组合。它返回每个组合的总数(repetitions)以及组合中的last_name和first_name。
具体来说,这个查询:
结果将按照last_name和first_name的顺序进行排序,并返回具有重复值的行。
SELECT DISTINCT
last_name,
first_name
FROM
person_table;
SELECT
last_name,
first_name
FROM
person_table
GROUP BY
last_name,
first_name;
SELECT DISTINCT * FROM (
SELECT column_name1, column_name2, ... FROM table_name
UNION
SELECT column_name1, column_name2, ... FROM table_name
) AS tmp;
这个方法会将表中的所有行复制到临时表中,并使用DISTINCT关键字删除重复的行。
DELETE table_name
FROM table_name
WHERE column_name IN (
SELECT column_name
FROM table_name
GROUP BY column_name
HAVING COUNT(*) > 1
);
这个方法将使用子查询查找具有重复值的列,并在主表中删除这些行。
DELETE table_name
FROM table_name
WHERE id NOT IN (
SELECT MIN(id)
FROM table_name
GROUP BY column_name
);
或者使用左连接
DELETE t1
FROM table_name t1
LEFT JOIN (
SELECT MIN(id) AS id
FROM table_name
GROUP BY column_name
) t2 ON t1.id = t2.id
WHERE t2.id IS NULL;
这两种方法都会从表中删除重复值,但不会删除包含重复值的列中的所有行。而是只删除重复值中的一行。
如何防止 SQL 注入攻击: