一、数据类型
选择合适的数据类型对于数据库性能和存储效率至关重要。下面介绍常见的数据类型及其特点:
1. 整数
整数类型 | 存储空间 | 表示范围 |
---|---|---|
TINYINT | 1 字节 | − 2 7 -2^{7} −27 到 2 7 − 1 2^{7}-1 27−1 |
SMALLINT | 2 字节 | − 2 15 -2^{15} −215 到 2 15 − 1 2^{15}-1 215−1 |
MEDIUMINT | 3 字节 | − 2 23 -2^{23} −223 到 2 23 − 1 2^{23}-1 223−1 |
INT | 4 字节 | − 2 31 -2^{31} −231 到 2 31 − 1 2^{31}-1 231−1 |
BIGINT | 8 字节 | − 2 63 -2^{63} −263 到 2 63 2^{63} 263-1 |
- UNSIGNED:表示不允许负值,将表示范围向上扩展。例如,
UNSIGNED TINYINT
的范围是 0 0 0 到 2 8 − 1 2^{8}-1 28−1。 - 显示宽度:如
INT(1)
与INT(11)
,仅影响某些 MySQL 客户端工具的显示,不影响实际存储和计算。
2. 实数
- FLOAT:4 字节,单精度浮点数,用于需要节省存储空间且对精度要求不高的场景。
- DOUBLE:8 字节,双精度浮点数,MySQL 内部默认使用 DOUBLE 进行浮点数运算。
- DECIMAL:用于高精度计算,特别是金融计算。存储为字符串,精度较高,但性能较低。
CREATE TABLE financial_data ( amount DECIMAL(10,2) );
3. 字符串
字符串的长度定义为字符数,而非字节数。不同的字符集使用不同的字节数。
-
VARCHAR:用于存储可变长度字符串,只使用必要的空间。需要额外使用 1-2 个字节记录长度。
CREATE TABLE example ( name VARCHAR(255) );
-
CHAR:固定长度字符串,存储时会删除尾随空格,并在比较时用空格填充。
CREATE TABLE example ( code CHAR(10) );
-
BINARY 和 VARBINARY:存储二进制数据,类似 CHAR 和 VARCHAR,但用于二进制数据。
CREATE TABLE example ( binary_data VARBINARY(255) );
-
BLOB:用于存储大量二进制数据,如图像或文件。
CREATE TABLE example ( data BLOB );
-
TEXT:用于存储大文本数据。
CREATE TABLE example ( description TEXT );
4. 时间与日期
-
DATETIME:存储为整数,格式为 YYYYMMDDHHMMSS,不受时区影响。
CREATE TABLE example ( created_at DATETIME );
-
TIMESTAMP:存储为 UNIX 时间戳,依赖时区。
CREATE TABLE example ( updated_at TIMESTAMP );
二、表分区
表分区可以显著提高查询性能和管理大型表的数据。
-
水平分区(Range Partitioning):根据列的值范围进行分区。
CREATE TABLE sales ( id INT, sale_date DATE, amount DECIMAL(10,2) ) PARTITION BY RANGE (YEAR(sale_date)) ( PARTITION p0 VALUES LESS THAN (2020), PARTITION p1 VALUES LESS THAN (2021), PARTITION p2 VALUES LESS THAN (2022) );
-
列表分区(List Partitioning):根据列的具体值进行分区。
CREATE TABLE sales ( id INT, sale_region VARCHAR(10), amount DECIMAL(10,2) ) PARTITION BY LIST (sale_region) ( PARTITION pNorth VALUES IN ('North', 'East'), PARTITION pSouth VALUES IN ('South', 'West') );
-
哈希分区(Hash Partitioning):使用哈希函数对数据进行分区。
CREATE TABLE sales ( id INT, sale_date DATE, amount DECIMAL(10,2) ) PARTITION BY HASH (YEAR(sale_date)) PARTITIONS 4;
-
键分区(Key Partitioning):使用某个列的值进行分区,与哈希分区类似,但可以使用任意类型的列。
CREATE TABLE sales ( id INT, customer_id INT, sale_date DATE, amount DECIMAL(10,2) ) PARTITION BY KEY(customer_id) PARTITIONS 4;
-
将分区存储在不同的磁盘上:
PARTITION BY HASH(id) PARTITIONS 4 ( PARTITION p0 DATA DIRECTORY = '/home/data/mysql-8.0.27/data', PARTITION p1 DATA DIRECTORY = '/mnt/data/mysql-8.0.27/data', PARTITION p2 DATA DIRECTORY = '/mnt/data2/mysql-8.0.27/data', PARTITION p3 DATA DIRECTORY = '/mnt/data3/mysql-8.0.27/data' );
注意:确保指定目录的所有者是
mysql:mysql
,且不是 MySQL 原本的数据目录文件。
三、视图
视图是虚拟表,用于简化复杂查询、提高安全性和重用查询逻辑。
-
创建视图:
CREATE VIEW user_sales AS SELECT users.id, users.name, sales.amount FROM users JOIN sales ON users.id = sales.user_id;
-
使用视图:
SELECT * FROM user_sales WHERE amount > 100;
四、存储过程和函数
存储过程和函数可以封装业务逻辑,提高代码的复用性和一致性。
-
创建存储过程:
DELIMITER // CREATE PROCEDURE GetUserSales (IN userId INT) BEGIN SELECT * FROM sales WHERE user_id = userId; END // DELIMITER ;
-
调用存储过程:
CALL GetUserSales(1);
-
创建函数:
DELIMITER // CREATE FUNCTION CalculateDiscount (price DECIMAL(10,2)) RETURNS DECIMAL(10,2) BEGIN RETURN price * 0.9; END // DELIMITER ;
-
使用函数:
SELECT CalculateDiscount(100);
五、触发器
触发器在特定事件发生时自动执行,常用于维护数据完整性和自动化任务。
- 创建触发器:
CREATE TRIGGER before_insert_sales BEFORE INSERT ON sales FOR EACH ROW SET NEW.sale_date = IFNULL(NEW.sale_date, CURRENT_DATE);
六、数据库备份和恢复
定期备份和恢复策略是保证数据安全的重要部分。
-
备份数据库:
mysqldump -u username -p database_name > backup_file.sql
-
恢复数据库:
mysql -u username -p database_name < backup_file.sql
七、用户和权限管理
适当的用户和权限管理确保数据库的安全性和可控性。
-
创建用户:
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
-
授予权限:
GRANT SELECT, INSERT ON database_name.* TO 'newuser'@'localhost';
-
撤销权限:
REVOKE INSERT ON database_name.* FROM 'newuser'@'localhost';
-
删除用户:
DROP USER 'newuser'@'localhost';
通过了解和应用这些 Schema 管理相关的知识和技术,可以更好地设计、优化和维护 MySQL 数据库,提高整体性能和管理效率。