1、选取最适用的字段属性
MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。
另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。
对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。
2、使用连接(JOIN)来代替子查询(Sub-Queries)
MySQL 从41开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示:
DELETE FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )
使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL *** 作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询可以被更有效率的连接(JOIN) 替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:
SELECT FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )
如果使用连接(JOIN) 来完成这个查询工作,速度将会快很多。尤其是当salesinfo表中对CustomerID建有索引的话,性能将会更好,查询如下:
SELECT FROM customerinfo
LEFT JOIN salesinfoON customerinfoCustomerID=salesinfo
CustomerID
WHERE salesinfoCustomerID IS NULL
连接(JOIN) 之所以更有效率一些,是因为 MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
3、使用联合(UNION)来代替手动创建的临时表
MySQL 从 40 的版本开始支持 UNION 查询,它可以把需要使用临时表的两条或更多的 SELECT 查询合并的一个查询中。在客户端的查询会话结束的时候,临时表会被自动删除,从而保证数据库整齐、高效。使用 UNION 来创建查询的时候,我们只需要用 UNION作为关键字把多个 SELECT 语句连接起来就可以了,要注意的是所有 SELECT 语句中的字段数目要想同。下面的例子就演示了一个使用 UNION的查询。
SELECT Name, Phone FROM client
UNION
SELECT Name, BirthDate FROM author
UNION
SELECT Name, Supplier FROM product
4、事务
尽管我们可以使用子查询(Sub-Queries)、连接(JOIN)和联合(UNION)来创建各种各样的查询,但不是所有的数据库 *** 作都可以只用一条或少数几条SQL语句就可以完成的。更多的时候是需要用到一系列的语句来完成某种工作。但是在这种情况下,当这个语句块中的某一条语句运行出错的时候,整个语句块的 *** 作就会变得不确定起来。设想一下,要把某个数据同时插入两个相关联的表中,可能会出现这样的情况:第一个表中成功更新后,数据库突然出现意外状况,造成第二个表中的 *** 作没有完成,这样,就会造成数据的不完整,甚至会破坏数据库中的数据。要避免这种情况,就应该使用事务,它的作用是:要么语句块中每条语句都 *** 作成功,要么都失败。换句话说,就是可以保持数据库中数据的一致性和完整性。事物以BEGIN 关键字开始,COMMIT关键字结束。在这之间的一条SQL *** 作失败,那么,ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态。
BEGIN;
INSERT INTO salesinfo SET CustomerID=14;
UPDATE inventory SET Quantity=11
WHERE item='book';
COMMIT;
事务的另一个重要作用是当多个用户同时使用相同的数据源时,它可以利用锁定数据库的方法来为用户提供一种安全的访问方式,这样可以保证用户的 *** 作不被其它的用户所干扰。
5、锁定表
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户
来使用,事务造成的影响不会成为一个太大的问题;但假设有成千上万的用户同时访问一个数据库系统,例如访问一个电子商务网站,就会产生比较严重的响应延迟。
其实,有些情况下我们可以通过锁定表的方法来获得更好的性能。下面的例子就用锁定表的方法来完成前面一个例子中事务的功能。
LOCK TABLE inventory WRITE
SELECT Quantity FROM inventory
WHEREItem='book';
UPDATE inventory SET Quantity=11
WHEREItem='book';
UNLOCK TABLES
这里,我们用一个 SELECT 语句取出初始数据,通过一些计算,用 UPDATE 语句将新值更新到表中。包含有 WRITE 关键字的 LOCK TABLE 语句可以保证在 UNLOCK TABLES 命令被执行之前,不会有其它的访问来对 inventory 进行插入、更新或者删除的 *** 作。
6、使用外键
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。例如,外键可以保证每一条销售记录都指向某一个存在的客户。在这里,外键可以把customerinfo 表中的CustomerID映射到salesinfo表中CustomerID,任何一条没有合法CustomerID的记录都不会被更新或插入到 salesinfo中。
CREATE TABLE customerinfo
(
CustomerID INT NOT NULL ,
PRIMARY KEY ( CustomerID )
) TYPE = INNODB;
CREATE TABLE salesinfo
(
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY(CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo
(CustomerID) ON DELETECASCADE
) TYPE = INNODB;
注意例子中的参数“ON DELETE CASCADE”。该参数保证当 customerinfo 表中的一条客户记录被删除的时候,salesinfo 表中所有与该客户相关的记录也会被自动删除。如果要在 MySQL 中使用外键,一定要记住在创建表的时候将表的类型定义为事务安全表 InnoDB类型。该类型不是 MySQL 表的默认类型。定义的方法是在 CREATE TABLE 语句中加上 TYPE=INNODB。如例中所示。
7、使用索引
索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(), MIN()和ORDERBY这些命令的时候,性能提高更为明显。那该对哪些字段建立索引呢?一般说来,索引应建立在那些将用于JOIN, WHERE判断和ORDER BY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUM类型的字段来说,出现大量重复值是很有可能的情况,例如 customerinfo中的“province” 字段,在这样的字段上建立索引将不会有什么帮助;相反,还有可能降低数据库的性能。我们在创建表的时候可以同时创建合适的索引,也可以使用ALTER TABLE或CREATE INDEX在以后创建索引。此外,MySQL
从版本32323开始支持全文索引和搜索。全文索引在 MySQL 中是一个FULLTEXT类型索引,但仅能用于MyISAM 类型的表。对于一个大的数据库,将数据装载到一个没有FULLTEXT索引的表中,然后再使用ALTER TABLE或CREATE INDEX创建索引,将是非常快的。但如果将数据装载到一个已经有FULLTEXT索引的表中,执行过程将会非常慢。
8、优化的查询语句
绝大多数情况下,使用索引可以提高查询的速度,但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用。下面是应该注意的几个方面。首先,最好是在相同类型的字段间进行比较的 *** 作。在MySQL 323版之前,这甚至是一个必须的条件。例如不能将一个建有索引的INT字段和BIGINT字段进行比较;但是作为特殊的情况,在CHAR类型的字段和 VARCHAR类型字段的字段大小相同的时候,可以将它们进行比较。其次,在建有索引的字段上尽量不要使用函数进行 *** 作。
例如,在一个DATE类型的字段上使用YEAE()函数时,将会使索引不能发挥应有的作用。所以,下面的两个查询虽然返回的结果一样,但后者要比前者快得多。
SELECT FROM order WHERE YEAR(OrderDate)<2001;
SELECT FROM order WHERE OrderDate<"2001-01-01";
同样的情形也会发生在对数值型字段进行计算的时候:
SELECT FROM inventory WHERE Amount/7<24;
SELECT FROM inventory WHERE Amount<247;
上面的两个查询也是返回相同的结果,但后面的查询将比前面的一个快很多。第三,在搜索字符型字段时,我们有时会使用 LIKE 关键字和通配符,这种做法虽然简单,但却也是以牺牲系统性能为代价的。例如下面的查询将会比较表中的每一条记录。
SELECT FROM books
WHERE name like "MySQL%"
但是如果换用下面的查询,返回的结果一样,但速度就要快上很多:
SELECT FROM books
WHERE name>="MySQL"and name<"MySQM"
最后,应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。
下面以比较流行的mysql图形化管理工具Navicat为例,其他工具或者在命令行中以及编程语言中 *** 作时的执行的sql语句是一样的。
1、假设在数据库中有一个名为testtest的表格,表格内容如下图所示,表中有三条记录是9月份的
2、打开一个查询窗口,输入查询语句select from testtest where month(date)='9';,该语句表示查询testtest表格中9月份的记录
3、点击“运行”执行该sql语句,在下方可以看到已经查询到了9月份的三条记录
4、如需按年查询可输入select from testtest where year(date)='2017';,2017代表需要查询的年份。如下图所示只查询到了一条记录是2017年的
相对于传统的自建数据库,移动云云数据库MySQL有以下优势:
1、管理简单:移动云云数据库MySQL的管理比传统的自建数据库更加简单,因为移动云平台为您提供了一系列自动化管理工具,如备份、监控、扩容、负载均衡等,使得您不需要太多的技术经验就可以方便地管理您的数据库。
2、可扩展性强:如果您的业务增长导致数据库压力增大,移动云云数据库MySQL可以很方便地扩容,根据业务需要自动增加存储容量和计算能力。
3、高可用性:移动云云数据库MySQL提供了高可用架构,采用主从复制的方式实现数据的备份和容灾,即使主节点故障,也可以快速切换到从节点保证数据库的连续性。
4、数据安全性高:移动云云数据库MySQL在安全方面提供了完善的保护机制,包括访问控制、数据加密、DDoS攻击防御等,可以保障您的数据不会被黑客攻击、误删除、泄露等问题。
5、节约成本:移动云云数据库MySQL采用按需付费的方式,您只需要按照实际使用量付费,不需要购买服务器、网络等基础设施,可以降低IT部署和运维成本。
综上所述,移动云云数据库MySQL相对于传统的自建数据库,具有更强的可扩展性、高可用性、数据安全性和成本优势等。同时,移动云平台提供的管理工具可以减轻您的管理负担,让您更加专注于核心业务的开发和创新。
MySQL数据库的表是一个二维表,由一个或多个数据列构成。
每个数据列都有它的特定类型,该类型决定了MySQL如何看待该列数据,我们可以把整型数值存放到字符类型的列中,MySQL则会把它看成字符串来处理。
MySQL中的列类型有三种:数值类、字符串类和日期/时间类。
从大类来看列类型和数值类型一样,都是只有三种。但每种列类型都还可细分。
下面对各种列类型进行详细介绍。
数值类的数据列类型
数值型的列类型包括整型和浮点型两大类。
TINYINT:1字节 非常小的正整数,带符号:-128~127,不带符号:0~255
SMALLINT:2字节 小整数,带符号:-32768~32767,不带符号:0~65535
MEDIUMINT:3字节 中等大小的整数,带符号:-8388608~8388607,不带符号:0~16777215
INT:4字节 标准整数,带符号:-2147483648~2147483647,不带符号:0~4294967295
BIGINT:8字节 大整数,带符号:-9223372036854775808~9233372036854775807,不带符号:0~18446744073709551615
FLOAT:4字节 单精度浮点数,最小非零值:+-1175494351E-38,最大非零值:+-3402823466E+38
DOUBLE:8字节 双精度浮点数,最小非零值:+-22250738585072014E-308,最大非零值:+-17976931348623157E+308
DECIMAL:M+2字节 以字符串形式表示的浮点数,它的取值范围可变,由M和D的值决定。
MYSQL支持大量的列类型,它们可以被分为 3 类:数字类型、日期和时间类型以及字符串(字符)类型。这个章节首先给出可用类型的概述,并且总结各类型所需的存储需求,然后提供各类型中的类型范畴更详细的描述。概述有意地简化了。更详细的说明应该参考特写列类型的附加信息,例如你能为其指定值的允许格式。
MySQL 支持的列类型在下面列出。下列代码字母用于描述中:
M指出最大的显示尺寸。最大的显示尺寸长度为 255。D适用于浮点类型。指出跟随在十进制小数点后的数字数量。最大可能值为 30,但不应大于M-2。
方括号 (“[”and“]”) 指定可选的类型修饰部份。
注意,如果为一个列指定了ZEROFILL,MySQL 将自动为这个列添加UNSIGNED属性。
警告:你应该知道当在两个整数类型值中使用减法时,如有一个为UNSIGNED类型,那么结果也是无符号的。查看章节635 Cast 函数。
TINYINT[(M)] [UNSIGNED] [ZEROFILL]-128到127。无符号的范围是0到255。
BITBOOL它们是TINYINT(1)的同义词。
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]一个小整数。有符号的范围是-32768到32767。无符号的范围是0到65535。
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]一个中等大小的整数。有符号的范围是-8388608到8388607。无符号的范围是0到16777215。
INT[(M)] [UNSIGNED] [ZEROFILL]一个正常大小的整数。有符号的范围是-2147483648到2147483647。无符号的范围是0到4294967295。
INTEGER[(M)] [UNSIGNED] [ZEROFILL]INT的同义词。
BIGINT[(M)] [UNSIGNED] [ZEROFILL]一个大的整数。有符号的范围是-9223372036854775808到9223372036854775807。无符号的范围是0到18446744073709551615。
你应该知道的有关BIGINT列的一些事情:
BIGINT或DOUBLE值来完成的,因此你不应该使用大于9223372036854775807(63 bits) 的无符号大整数,除了位函数之外!如果你这样做了,结果中的某些大数字可能会出错,因为将BIGINT转换成DOUBLE时产生了舍入错误。MySQL 40 在下列情况下可以处理BIGINT:
在一个BIGINT列中使用整数存储一个大的无符号值。
在MIN(big_int_column)和MAX(big_int_column)中。
当两个 *** 作数都是整数时使用 *** 作符 (+、-、、等)。
通常你可以在一个BIGINT列中以字符串方式存储的一个精确的整数。在这种情况下,MySQL 将执行一个字符串到数字的转换,包括无 intermediate 的双精度表示法。
当两个参数均是整数值时,“-”、“+”和“”将使用BIGINT运算!这就意味着,如果两个大整数的乘积(或函数的结果返回整数)的结果大于9223372036854775807时,你可能会得到意想不到的结果。
FLOAT(precision) [UNSIGNED] [ZEROFILL]一个浮点型数字。
precision可以是<=24作为一个单精度的浮点数字和介于 25 和 53 之间作为一个双精度的浮点数字。这些类型与下面描述的FLOAT和DOUBLE类型相似。FLOAT(X)有与相应的FLOAT和DOUBLE类型同样的范围,但是显示尺寸和十进制小数位数是未定义的。在 MySQL 323 中,它是一个真实的浮点值。而在 MySQL 早期的版本中,FLOAT(precision)通常有 2 小数位。 注意,由于在 MySQL 中所有的计算都是以双精度执行的,所以使用FLOAT可能带来一些意想不到的问题。查看章节A56 解决没有匹配行的问题。
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]一个小的(单精度) 浮点数字。允许的值是-3402823466E+38到-1175494351E-38、0和1175494351E-38到3402823466E+38。如果UNSIGNED被指定,负值是不允许的。M是显示宽度,D是小数位数。FLOAT没有参数或有X<= 24 的FLOAT(X)代表一个单精度的浮点数字。
DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]一个正常大小的(双精度)浮上数字。允许的值是-17976931348623157E+308到-22250738585072014E-308、0和22250738585072014E-308到17976931348623157E+308。如果UNSIGNED被指定,负值是不允许的。M是显示宽度,D是小数位数。DOUBLE没胡参数或有 25 <=X<= 53 的FLOAT(X)代表一个双精度的浮点数字。
DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL]
REAL[(M,D)] [UNSIGNED] [ZEROFILL]它们是DOUBLE同义词。
DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]一个未压缩(unpacked)的浮点数。运作如同一个CHAR列:“unpacked” 意味着数字是以一个字符串存储的,值的每一位将使用一个字符。小数点并且对于负数,“-”符号不在M中计算(但是它们的空间是被保留的)。如果D是 0,值将没有小数点或小数部份。DECIMAL值的最大范围与DOUBLE一致,但是对于一个给定的DECIMAL列,实际的范围可以被所选择的M和D限制。如果UNSIGNED被指定,负值是不允许的。 如果D被忽略,缺省为 0。如果M被忽略,缺省为 10。 在 MySQL 323 以前,M参数必须包含符号与小数点所需的空间。
DEC[(M[,D])] [UNSIGNED] [ZEROFILL]
NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL]DECIMAL的同义词。
DATE一个日期。支持的范围是'1000-01-01'到'9999-12-31'。MySQL 以'YYYY-MM-DD'格式显示DATE值,但是允许你以字符串或数字给一个DATE列赋值。查看章节6222DATETIME、DATE和TIMESTAMP类型。
DATETIME一个日期和时间的组合。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。MySQL 以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,但是允许你以字符串或数字给一个DATETIME列赋值。查看章节6222DATETIME、DATE和TIMESTAMP类型。
TIMESTAMP[(M)]一个时间戳。范围是'1970-01-01 00:00:00'到2037年间的任意时刻。 MySQL 40 和更早版本中,TIMESTAMP值是以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD格式显示的,它取决于M是否是14(或省略)、12、8或6,但是允许你以字符串或数字给一个TIMESTAMP列赋值。 从 MySQL 41 开始,TIMESTAMP以'YYYY-MM-DD HH:MM:DD'格式作为字符返回。如果你你希望以数字形式返回则必须在该时间戳字段后加上 +0。不同的时间戳长度是不支持的。从 MySQL 4012 开始,选项--new可以被用来使服务器与 41 一样运作。TIMESTAMP列有益于记录一个INSERT或UPDATE *** 作的日期和时间,因为如果你自己没有给它赋值,它将被自动地设置为最近一次 *** 作的日期和时间。也可以通过给它赋一个NULL而使它设置为当前的日期和时间。查看章节622 Date 和 Time 类型。 参数M只影响一个TIMESTAMP列的显示格式;它的值总是占用 4 个字节存储。 注意,当TIMESTAMP(M)列的M是 8 或 14 时,它返回的是数字而其它的TIMESTAMP(M)列返回的是字符串。这仅仅是为了可以可靠地转储并恢复到其它格式的表中。查看章节6222DATETIME、DATE和TIMESTAMP类型。TIME一个时间。范围是'-838:59:59'到'838:59:59'。MySQL 以'HH:MM:SS'格式显示TIME值,但是允许你使用字符串或数字来给TIME列赋值。查看章节6223TIME类型。YEAR[(2|4)]一个 2 或 4 位数字格式的年(缺省为 4 位)。允许的值是1901到2155、0000(4 位年格式) 以及使用 2 位格式的 1970-2069 (70-69)。MySQL 以YYYY格式显示YEAR值,但是允许你使用字符串或数字来给YEAR列赋值。(YEAR类型在 MySQL 322 之前不支持。) 查看章节6224YEAR类型。
[NATIONAL] CHAR(M) [BINARY]一个定长的字符串,当存储时,总是以空格填满右边到指定的长度。M的范围是 0 到 255 (在 MySQL 323 版本之前为 1 到 255)。当该值被检索时,尾部空格将被删除。CHAR值根据缺省的字符集进行忽略大小写的排索与比较,除非指定了关键词BINARY。NATIONAL CHAR(或短形式NCHAR) 是以 ANSI SQL 方式定义一个CHAR列,它将使用缺省的字符集。这在 MySQL 中是默认的。
CHAR是CHARACTER的缩写。 MySQL 允许以CHAR(0)类型建立一个列。一些老程序运行时必需一个列,却又并不使用这个列的值,你就不得不为了适应它而建立该列,在这情况下,CHAR(0)将是很有益的。当需要一个列仅保存两个值时:一个为CHAR(0)(该列没有定义为NOT NULL),这将仅占用一个比特位来存储 2 个值:NULL或""。查看章节6231CHAR和VARCHAR类型。CHAR这是CHAR(1)的同义词。
[NATIONAL] VARCHAR(M) [BINARY]一个变长的字符串。注意:尾部的空格在存储时将会被删除(这与 ANSI SQL 约规不同)。M的范围是 0 到 255 (在 MySQL 402 之前的版本中是 1 到 255)。
VARCHAR值以大小写忽略方式进行排索与比较,除非关键词BINARY被指定。查看章节6531 隐式的列定义变化。VARCHAR是CHARACTER VARYING的缩写。查看章节6231CHAR和VARCHAR类型。
TINYBLOBTINYTEXT一个BLOB或TEXT列,最大长度为 255 (2^8 - 1) 个字符。查看章节6531 隐式的列定义变化。查看章节6232BLOB和TEXT类型。
BLOBTEXT一个BLOB或TEXT列,最大长度为 65535 (2^16 - 1) 个字符。查看章节6531 隐式的列定义变化。查看章节6232BLOB和TEXT类型。
MEDIUMBLOBMEDIUMTEXT一个BLOB或TEXT列,最大长度为 16777215 (2^24 - 1) 个字符。查看章节6531 隐式的列定义变化。查看章节6232BLOB和TEXT类型。
LONGBLOBLONGTEXT一个BLOB或TEXT列,最大长度为 4294967295 (2^32 - 1) 个字符。查看章节6531 隐式的列定义变化。注意,由于服务器/客户端的协议以及 MyISAM 表通常有一个 16M 每通信包/表行的限制,你仍然不能使用这个类型的整个范围。查看章节6232BLOB和TEXT类型。ENUM('value1','value2',)一个枚举类型。一个仅能有一个值的字符串对象,这个值选自值列'value1'、'value2'、、NULL或特殊的""出错值。一个ENUM列可以有最大 65535 不同的值。查看章节6233ENUM类型。SET('value1','value2',)一个集合。一个能有零个或更多个值的字符串对象,其中每个值必须选自值列'value1'、'value2'、。一个SET列可以有最大 64 个成员。查看章节6234SET类型。
MySQL 支持所有的 ANSI/ISO SQL92 数字类型。这些类型包括准确数字的数据类型(NUMERIC、DECIMAL、INTEGER和SMALLINT),也包括近似数字的数据类型(FLOAT、REAL和DOUBLE PRECISION)。关键词INT是INTEGER的同义词,关键词DEC是DECIMAL的同义词。
NUMERIC和DECIMAL类型被 MySQL 以同样的类型实现,这在 SQL92 标准中是允许的。他们用于保存对准确精度有重要要求的值,例如与金钱有关的数据。当以它们中的之一声明一个列时,精度和数值范围可以(通常是)被指定;例如:
salary DECIMAL(5,2)
在这个例子中,5(精度(precision)) 代表重要的十进制数字的数目,2(数据范围(scale)) 代表在小数点后的数字位数。在这种情况下,因此,salary列可以存储的值范围是从-9999到9999。(实际上 MySQL 在这个列中可以存储的数值可以一直到99999,因为它没有存储正数的符号)。
译者注:
M 与D 对DECIMAL(M, D) 取值范围的影响
类型说明 取值范围(MySQL < 323) 取值范围(MySQL >= 323)
DECIMAL(4, 1) -99 到 999 -9999 到 99999
DECIMAL(5, 1) -999 到 9999 -99999 到 999999
DECIMAL(6, 1) -9999 到 99999 -999999 到 9999999
DECIMAL(6, 2) -9999 到 99999 -999999 到 9999999
DECIMAL(6, 3) -9999 到 99999 -999999 到 9999999
# 在MySQL 323 及以后的版本中,DECIMAL(M, D) 的取值范围等于早期版本中的DECIMAL(M + 2, D) 的取值范围。注释结束:
在 ANSI/ISO SQL92 中,句法DECIMAL(p)等价于DECIMAL(p,0)。同样的,在执行被允许决定值p的地方,句法DECIMAL等价于DECIMAL(p,0)。MySQL 目前还不支持DECIMAL/NUMERIC数据类型的这些变体形式中的任一种。一般来说这并不是一个严重的问题,通过明确地控制精度和数值范围可以得到这些类型的主要功能益处。
DECIMAL和NUMERIC值是作为字符串存储的,而不是作为二进制浮点数,以便保护这些值的十进制精确度。一个字符用于数值的每一位、小数点(如果scale> 0) 和“-”符号(对于负值)。如果scale是 0,DECIMAL和NUMERIC值不包含小数点或小数部分。
DECIMAL和NUMERIC值的最大范围与DOUBLE一致,但是对于一个给定的DECIMAL或NUMERIC列,它的实际范围可制定该列时的precision或scale限制。当这样的列被赋给了小数点的位数超过scale所指定的值时,该将根据scale进行四舍五入。当一个DECIMAL或NUMERIC列被赋与一个大小超过指定(或缺省)的precisionandscale的限止范围时,MySQL 以该列范围的端点值存储该值。
表统计信息是数据库基于成本的优化器最重要的参考信息;统计信息不准确,优化器可能给出不够优化的执行计划或者是错误的执行计划。对统计信息的计算分为非持久化统计信息(实时计算)与持久化统计信息。
非持久化统计信息
统计信息没有保存在磁盘上,而是频繁的实时计算统计信息;
每次对表的访问都会重新计算其统计信息;
假设针对一张大表的频繁查询,那么每次都要重新计算统计信息,很耗费资源。
持久化统计信息
把一张表在某一时刻的统计信息值保存在磁盘上;
避免每次查询时重新计算;
如果表更新不是很频繁,或者没有达到 MySQL 必须重新计算统计信息的临界值,可直接从磁盘上获取;
即使 MySQL 服务重启,也可以快速的获取统计信息值;
统计信息的持久化可以针对全局设置也可以针对单表设置。
接下来,详细说 MySQL 统计信息如何计算,何时计算,效果评估等问题。在 MySQL Server 层来控制是否自动计算统计信息的分布,并且来决策是持久化还是非持久化。
对于想要将自动生成的数据添加到表中的任何人来说, MySQL 虚拟列 是一个强大、易于使用和高级的功能。
INSERT 生成的列允许您在不使用and UPDATE 子句的情况下将自动生成的数据存储在表中。 这个有用的特性自 57 版 起就已成为 MySQL 的一部分,它代表了在生成数据时触发器的另一种方法。此外,生成的列可以帮助您更轻松、更高效地查询。
虚拟列 列类似于普通列,但您不能手动更改其值。这是因为表达式定义了如何根据从同一行的其他列中读取的其他值来生成生成列的值。因此,生成的列在表的域内工作,其定义不能涉及 JOIN 语句。
换句话说,您可以将生成的列视为一种视图,但仅限于列。请注意,生成的列与 SQL 触发器 不同,您只能在使用 CREATE TABLE or语句时定义它们,语法如下: ALTER TABLE
该 AS (generated_column_expression) 子句指定要添加或更新到表中的列是生成的列。定义 MySQL 将用于计算列值的 generation_expression 表达式,它不能引用另一个生成的列或除当前表的列之外的任何内容。另外,请注意生成表达式只能涉及不可变函数。例如,您不能在生成的列表达式定义中使用返回当前日期的函数,因为它是一个可变函数。
您还可以在关键字前面 AS 加上 GENERATED ALWAYS 关键字以使生成的列的性质更加明确,但这是可选的。然后,您可以指示生成列的类型是 VIRTUAL 还是 STORED 。您将在下面的章节中了解这两种类型之间的区别。默认情况下,如果没有在查询中明确指定,MySQL 会将生成的列标记为 VIRTUAL
现在让我们看看生成的列语法在 CREATE TABLE 查询中的作用:
在此示例中,该 full_name 列将自动存储 first_name 和 last_name 列的连接。
如前所述,您可以将生成的列定义为 VIRTUAL 或 STORED。现在让我们仔细看看这两种类型。
MySQL 不存储标记为 VIRTUAL 的 虚拟列 。这意味着 MySQL 在需要时动态评估其值。 BEFORE 这通常在触发任何查询后立即发生。换句话说,虚拟生成的列不占用存储空间。
MySQL 存储任何生成的标记为 STORED 的列。这意味着每次插入或更新行时,MySQL 都会评估其值并将其存储在磁盘上。换句话说,存储列需要存储空间,就好像它是普通列一样。
现在让我们进一步了解虚拟列和存储生成列的优缺点。
优点
缺点
优点
缺点
采用生成的列有几个原因,但以下三个是最重要的。
如您所见,您可以通过将四列与以下生成的列聚合来轻松生成此数据字段:
这将产生:
在这种情况下,生成的列使您能够直接在数据库级别标准化数据字段格式。此外,存储生成的列避免了每次需要时都构造此字段的不可避免的开销。
通常,您使用网站 URL 中的资源 ID 或REST API来检索您需要的数据。但是公开暴露您的 ID 可能会带来安全问题。当您发现自己使用自动增量 ID 时尤其如此,这很容易预测并使抓取或机器人攻击更容易。
为避免这种情况,您可以考虑通过使用自动生成的、随机的、更安全的公共 ID 来隐藏您的原始 ID。您可以通过对您的 ID 进行散列处理,使用虚拟生成的列来实现这一点,如下所示:
请注意,为避免生成已知的哈希值,您可以将您的 ID 与特殊关键字连接起来。 在此处了解有关 MySQL 加密和压缩功能的更多信息。
过滤数据时,有些列比其他列更有用。此外,您通常必须更改存储在列中的值的表示形式,以使过滤更简单或更直观。您可以定义一个有用的生成列来存储以所需格式执行过滤所需的信息,而不是在每个过滤器查询中执行此 *** 作。
例如,您可以定义一个生成的列,以便更轻松地找到篮球队中的球员,如下所示:
这样的列将产生:
如前所述,您只能在表中使用生成的列。此外,它们只能涉及不可变函数,并且MySQL 生成它们的值以响应 INSERT or UPDATE 查询。另一方面,触发器是 MySQL 自动执行的存储程序,每当与特定表关联的 或 事件发生 INSERT 时 UPDATE 。 DELETE 换句话说,触发器可以涉及多个表和所有 MySQL 函数。与生成的列相比,这使它们成为更完整的解决方案。同时,MySQL 触发器本质上使用和定义更复杂,也比生成的列慢。
以上就是关于MySQL 使用技巧全部的内容,包括:MySQL 使用技巧、在MySql中、怎样根据年份或者月份查询数据表中的数据、移动云云数据库MySQL对比传统自建数据库有什么优势等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)