Tài liệu MySQL Administrator’s Bible- P5 pdf

50 324 0
Tài liệu MySQL Administrator’s Bible- P5 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

MySQL Data Types TABLE 5-1 Summary of MySQL Character String Types Data Type Name SQL Standard? Fixed/Variable Length CHAR Yes VARCHAR Range Size Attributes Fixed Length of 0–255, depends on character set M*x bytes ASCII BINARY CHARACTER SETCOLLATION DEFAULT UNICODE Yes Variable Length of 0–255, depends on character set L*x+1 if L255 ASCII BINARY CHARACTER SETCOLLATION DEFAULT UNICODE TINYTEXT No Variable Max length of 255 bytes L+1 bytes byte stores length ASCII BINARY CHARACTER SETCOLLATION UNICODE TEXT No Variable Max length of 65,535 bytes (64 Kb) L+2 bytes bytes store length ASCII BINARY CHARACTER SETCOLLATION UNICODE MEDIUMTEXT No Variable Max length of 16,777,215 bytes (16 Mb) L+3 bytes bytes store length ASCII BINARY CHARACTER SETCOLLATION UNICODE LONGTEXT No Variable Max length of L+4 bytes 4,294,967,295 bytes store bytes (4 Gb) length ASCII BINARY CHARACTER SETCOLLATION NOT NULL NULL UNICODE Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 167 Part II Developing with MySQL Like character string types, MySQL supports the SQL standard for fixed- and variable-length strings, but not for character objects The SQL standard states that the NATIONAL equivalents of character string types are the same as the character string types, except that a specific character set is used In MySQL, this character set is utf8: mysql> CREATE TABLE nchar_test (nchar_fld NCHAR(10)); Query OK, rows affected (0.55 sec) mysql> SHOW CREATE TABLE nchar_test\G *************************** row *************************** Table: nchar_test Create Table: CREATE TABLE `nchar_test` ( `nchar_fld` char(10) CHARACTER SET utf8 DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 row in set (0.00 sec) The characteristics and usage of national character string types is exactly the same as character string types, with one exception: the ASCII and UNICODE attributes are not proper syntax This is because the ASCII and UNICODE attributes set the character set, which conflicts with the NATIONAL keyword For details on character string types, see the section ‘‘Character String Types’’ earlier in this chapter Binary Large Object String Types A binary string type is the least restrictive data type There is one binary large object type in the ISO SQL:2003 standard, with two aliases: ■ BINARY LARGE OBJECT(length) ■ BLOB(length) MySQL supports only the second standard syntax, BLOB(length) However, MySQL extends the SQL standard for binary large object string types with five additional binary types: ■ TINYBLOB ■ MEDIUMBLOB ■ LONGBLOB ■ BINARY(length) ■ VARBINARY(length) 168 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types Binary string types are byte strings Character strings are ordered lexically; binary strings are ordered by each byte’s value The standard does not specify what makes an object ‘‘large,’’ and there is no standard equivalent for smaller binary strings, so we have included the smaller BINARY and VARBINARY byte string types into this category BLOB values The four BLOB types are very similar to each other — the only differences are the maximum amount of data each can store and the overhead involved in storing the size of each record: ■ TINYBLOB — Up to 255 bytes, byte overhead ■ BLOB — Up to 64 Kb, bytes overhead ■ MEDIUMBLOB — Up to 16 Mb, bytes overhead ■ LONGBLOB — Up to Gb, bytes overhead A BLOB data type field is a separately allocated object than the table that contains it, like the TEXT data type fields BINARY values BINARY and VARBINARY are similar to the CHAR and VARCHAR data types, respectively For the BINARY and VARBINARY data types, the length is an integer representing the length, in bytes, of a string A data type of BINARY or VARBINARY with a length of is valid, but can hold only two strings: the empty string and NULL Note that BINARY and VARBINARY are different from CHAR BINARY and VARCHAR BINARY — BINARY and VARBINARY are byte strings, and CHAR BINARY and VARCHAR BINARY are case-sensitive character strings BINARY length The length of BINARY is an integer from 0–255 If a string is stored as a BINARY and is smaller than the length, binary spaces (represented by \0) are appended to the string A binary space is different from a regular space character; a binary space has an ASCII value of and the regular space character has an ASCII value of 32: mysql> SELECT ’ ’,ASCII(’ ’), ’\0’, ASCII(’\0’); + -+ + -+ -+ | | ASCII(’ ’) | | ASCII(’\0’) | + -+ + -+ -+ | | 32 | | | + -+ + -+ -+ row in set (0.02 sec) Because of this, a value of ’a’ appears before a value of ’a ’ in an ascending sort This also means that the BINARY value ’a’ is the same as the BINARY value ’a\0’ for the purpose of unique constraints There is no removal of trailing spaces when a BINARY string is retrieved from a table Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 169 Part II Developing with MySQL VARBINARY length The maximum length of a VARBINARY is restricted only by the maximum row length In most storage engines, the maximum row length is the maximum allowed by MySQL, which is 65,535 bytes Only the NDB storage engine has a different maximum value Like a VARCHAR, in theory, the maximum length of a VARBINARY is 65,535 bytes In practice, there is some overhead in storing the VARBINARY data type, which further limits the actual possible size of a VARBINARY If the length of VARBINARY is less than 255 bytes, one byte per row is used to store the actual length of the string If the length of VARBINARY is greater than 255 bytes, the overhead cost of storing the string length is two bytes per row There is also per-table overhead — every table allocates one byte for every set of eight potentially nullable fields, regardless of field types Thus, the maximum length of a VARBINARY is 65,532 bytes, and that is only if the VARBINARY field is the only field in the table For example, another field with a type of INT uses bytes, so the maximum length of a VARBINARY in that table would be 65,528 bytes For VARBINARY strings larger than the maximum allowed, use the BLOB data type If you try to define a table that exceeds the maximum row length, you will get the following error: mysql> CREATE TABLE max_len_varbin(fld VARBINARY(65533)); ERROR 1118 (42000): Row size too large The maximum row size for the used table type, not counting BLOBs, is 65535 You have to change some columns to TEXT or BLOBs Table 5-2 shows a summary of the MySQL binary data types As with the character string data types, the numbers given in Table 5-2 are the basic storage requirements of MySQL The storage engine used may add additional overhead or provide data compression that reduces the storage required See Chapter 11 for more details about storage engines Numeric Types The ISO SQL:2003 standard defines two numeric types Each numeric type has a few different data types The standard numeric types and their associated keywords are: ■ Exact numeric type: ■ NUMERIC(g,f) ■ DECIMAL(g,f) can be abbreviated as DEC ■ SMALLINT ■ INTEGER can be abbreviated as INT ■ BIGINT 170 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types TABLE 5-2 Summary of MySQL Binary Data Types Data Type Name SQL Standard? Fixed/Variable Length BINARY No VARBINARY Range Size Attributes Fixed Length of 0–255 bytes M bytes DEFAULT NOT NULL NULL No Variable Length of 0–65,532 bytes L*x+1 if L255 DEFAULT NOT NULL NULL TINYBLOB No Variable Max length of 255 bytes L+1 bytes byte stores length NOT NULL NULL BLOB No Variable Max length of 65,535 bytes (64 Kb) L+2 bytes bytes store length NOT NULL NULL MEDIUMBLOB No Variable Max length of 16,777,215 bytes (16 Mb) L+3 bytes bytes store length NOT NULL NULL LONGBLOB No Variable Max length of 4,294,967,295 bytes (4 Gb) L+4 bytes bytes store length NOT NULL NULL ■ Approximate numeric type: ■ FLOAT(p) ■ REAL ■ DOUBLE PRECISION MySQL supports these data types with one exception — the DOUBLE PRECISION data type is simply named DOUBLE In addition, the NUMERIC data type is an alias for the DECIMAL data type The standard SQL has been extended to add these additional numeric data types: ■ Exact numeric types: ■ TINYINT ■ MEDIUMINT ■ BIT(x) ■ SERIAL In MySQL, the SERIAL numeric data type is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE KEY Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 171 Part II Developing with MySQL By default, the REAL numeric data type is an alias for DOUBLE However, you can change that behavior by changing the sql_mode to include REAL_AS_FLOAT, which causes the REAL numeric data type to be an alias for FLOAT See ‘‘Choosing SQL Modes’’ later in this chapter for more detail Numeric data sizes and ranges Each numeric data type can store a limited range of values, and each numeric data type stores its values in a certain size DECIMAL size and range A DECIMAL field is defined using the syntax DECIMAL(g,f) The first argument (g) is the total number of digits, and the second argument (f) is the number of digits after the decimal point For example, the data type DECIMAL(5,2) can store values between –999.99 and 999.99 The default value for g is 10 and the default value for f is 0; the maximum value for g is 65 and the maximum value for f is 30 The size of a DECIMAL field is variable MySQL stores DECIMAL in a binary format, where each group of digits is stored in bytes The size of a DECIMAL field is determined by the number of digits in the integer part (the value of p-s) and the number of digits in the fractional part (the value of s) The integer and fractional parts are stored separately in 4-byte, 9-digit groups If the number of digits in each group is not divisible by nine, the remaining digits are stored in CEILING(digits/2) bytes As an example, the size of DECIMAL(12,2) can be calculated as follows: Integer part = (12-2) digits = 10 digits = digits + digit digits = bytes digit left over CEILING(1/2) = byte Total integer part = bytes Fractional part = digits CEILING(2/2) = byte Total size = bytes Integer sizes and ranges The integer data types are TINYINT, SMALLINT, INT, MEDIUMINT, and BIGINT Table 5-3 shows the data sizes and ranges for the integer data types: Note that the size of the field is the size of the data type, not the size of the value stored For example, the value 123 stored in a BIGINT field is stored in bytes The same value 123 stored in a TINYINT field is stored in byte 172 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types TABLE 5-3 Data Sizes and Ranges for Integer Data Types Data Type SIGNED Range UNSIGNED Range Size TINYINT –128 to 127 to 255 byte SMALLINT –32,768 to 32,767 to 65,535 bytes MEDIUMINT –8,388,608 to 8,388,607 to 16,777,215 bytes INT –2,147,483,648 to 2,147,483,647 to 4,294,967,295 bytes BIGINT –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 to 18,446,744,073,709,551,615 bytes MySQL allows a minimum display width to be set for integer types If an integer value is less than this width, the value will be left-padded with enough spaces so the value is displayed as this width This is only for the display and does not change the actual value returned This can be specified by giving the width as an argument to the integer data type, for example INT(4) This does not change the range nor the size of the data type, just the minimum display width MySQL performs calculations and comparisons using double-precision floating-point numbers Calculations using unsigned BIGINT values larger than 63 bits (9,223,372,036,854,775,807) should only be done via bit functions BIT size and range The BIT data type stores integers as a series of bits The range of a BIT field is determined by the argument to BIT(x) The default range is bit and the range can be set from to 64 bits The BIT values are stored in binary format (that is, it is stored in base 2, as opposed to decimal format, which is stored in base 10) Unlike other data types, a BIT value needs to be converted upon retrieval to produce a human-readable result How to retrieve BIT values depends on whether you want to retrieve integers or bit strings: mysql> USE test; Database changed mysql> CREATE TABLE bit_test (bt BIT(10)); Query OK, rows affected (0.64 sec) mysql> INSERT INTO bit_test (bt) VALUES (0),(1),(2),(3),(4); Query OK, rows affected (11.78 sec) Records: Duplicates: Warnings: Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 173 Part II Developing with MySQL mysql> SELECT bt,bt+0,BIN(bt) FROM bit_test; + + + -+ | bt | bt+0 | BIN(bt) | + + + -+ | | | | | | | | | | | 10 | | ♥ | | 11 | | ♦ | | 100 | + + + -+ rows in set (0.09 sec) The BIT value, as it is stored, is shown in the first field of the result As you can see, it is not in human-readable format The second field of the result casts the result as an integer, and the third field casts the result as a bit string FLOAT size and range The FLOAT data type is a single-precision floating-point number Floating-point means that unlike the DECIMAL data type, the decimal point can be anywhere in the number — the decimal point floats A FLOAT is limited in how many significant digits it can store In the SQL standard, this limitation can be specified as the argument p (p stands for precision) In MySQL, this limitation depends on the hardware and operating system, but is usually a precision of 24 bits This translates to or significant digits, and a storage cost of bytes per FLOAT If a FLOAT field is defined with a larger value of p, it is changed into a DOUBLE field: mysql> USE test; Database changed mysql> CREATE TABLE float_double_test ( -> f1 FLOAT(1), f2 FLOAT(10), f3 FLOAT(23), -> f4 FLOAT(24), f5 FLOAT(53)); Query OK, rows affected (0.16 sec) mysql> SHOW CREATE TABLE float_double_test\G *************************** row *************************** Table: float_double_test Create Table: CREATE TABLE `float_double_test` ( `f1` float DEFAULT NULL, `f2` float DEFAULT NULL, `f3` float DEFAULT NULL, `f4` float DEFAULT NULL, `f5` double DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 row in set (0.06 sec) mysql> ALTER TABLE float_double_test ADD COLUMN f6 FLOAT(54); ERROR 1063 (42000): Incorrect column specifier for column ’f6’ 174 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types A significant digit is a digit that signifies precision, and not a power of ten The following example was done on a system where the number of significant digits is six: mysql> CREATE TABLE float_test (ft float, ft_text varchar(10)); Query OK, rows affected (0.59 sec) mysql> INSERT INTO float_test (ft,ft_text) VALUES -> (1234567,’1234567’), (123456,’123456’), (12345.6,’12345.6’), -> (123.456,’123.456’), (1.23456,’1.23456’), -> (0.00123456,’0.00123456’), -> (1.23456e-3,’1.23456e-3’), (123456000,’123456000’), -> (1.23456e8,’1.23456e8’), (123456e3,’123456e3’); Query OK, 10 rows affected (0.08 sec) Records: 10 Duplicates: Warnings: mysql> SELECT ft, ft_text FROM float_test ORDER BY ft; + + + | ft | ft_text | + + + | 0.00123456 | 0.00123456 | | 0.00123456 | 1.23456e-3 | | 1.23456 | 1.23456 | | 123.456 | 123.456 | | 12345.6 | 12345.6 | | 123456 | 123456 | | 1234570 | 1234567 | | 123456000 | 123456000 | | 123456000 | 1.23456e8 | | 123456000 | 123456e3 | + + + 10 rows in set (0.06 sec) Note that the values 123456000, 1.23456e8 and 123456e3 are all the same floating-point number The numbers including e indicate scientific notation, replacing e with *10 ˆ Indeed, 123456000, 1.23456*10 ˆ and 123456*10 ˆ all signify the same number MySQL automatically rounded the value with more than six significant digits to have exactly six significant digits — the value 1234567 was rounded to 1234570 As mentioned previously, MySQL supports the SQL standard FLOAT(p) syntax It also supports a syntax similar to the DECIMAL syntax A FLOAT field can be defined as in the preceding example, or it can be defined as FLOAT(g,f) The first argument (g) is the total number of digits, and the second argument (f) is the number of digits after the decimal point The FLOAT(g,f) syntax can be used to override the default amount of significant digits Therefore, higher or lower precision can be specified using the two-argument syntax It should be noted that this is not an exact substitute for defining precision, because the number of digits after the decimal point is fixed Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 175 Part II Developing with MySQL MySQL performs calculations and comparisons using double-precision floating-point numbers Queries involving a FLOAT field may return unexpected results; rounding an (internal) DOUBLE number often does not yield the same result as rounding a FLOAT number Therefore, comparing a FLOAT field to a calculated number will often produce incorrect results, because the calculated number is a DOUBLE The following example shows that calculating a FLOAT value (by adding 0) changes it to a DOUBLE value, which can produce a very different value from the original FLOAT: mysql> SELECT ft_text, ft, ft+0 FROM float_test; + + + -+ | ft_text | ft | ft+0 | + + + -+ | 1234567 | 1234570 | 1234567 | | 123456 | 123456 | 123456 | | 12345.6 | 12345.6 | 12345.599609375 | | 123.456 | 123.456 | 123.45600128173828 | | 1.23456 | 1.23456 | 1.2345600128173828 | | 0.00123456 | 0.00123456 | 0.00123456004075706 | | 1.23456e-3 | 0.00123456 | 0.00123456004075706 | | 123456000 | 123456000 | 123456000 | | 1.23456e8 | 123456000 | 123456000 | | 123456e3 | 123456000 | 123456000 | + + + -+ 10 rows in set (0.04 sec) DOUBLE size and range The DOUBLE data type is a double-precision floating-point number Like a FLOAT, a DOUBLE is limited in how many significant digits it can store See previous subsection ‘‘FLOAT Size and Range’’ for an explanation of floating-point numbers and significant digits The data type is named DOUBLE because the limitation is approximately double the limitation of a single-precision FLOAT As with FLOAT, this limitation depends on the hardware and operating system, but is usually a precision of 53 bits This translates to 14 or 15 significant digits, and a storage cost of bytes per DOUBLE As with FLOAT, MySQL supports a syntax similar to the DECIMAL syntax A DOUBLE field can be defined with no parameters as DOUBLE, or it can be defined as DOUBLE(g,f) The first argument (g) is the total number of digits, and the second argument (f) is the number of digits after the decimal point The DOUBLE(g,f) syntax can be used to override the default number of significant digits It should be noted that this is not an exact substitute for defining precision, because the number of digits after the decimal point is fixed 176 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Part II Developing with MySQL mysql> USE test; Database changed mysql> CREATE TABLE sql_mode_test (sm1 tinyint not null); Query OK, rows affected (0.20 sec) mysql> INSERT INTO sql_mode_test (sm1) VALUES (126); Query OK, row affected (0.13 sec) mysql> INSERT INTO sql_mode_test (sm1) VALUES (127); Query OK, row affected (0.09 sec) mysql> INSERT INTO sql_mode_test (sm1) VALUES (128); Query OK, row affected, warning (0.13 sec) mysql> SHOW WARNINGS; + -+ + + | Level | Code | Message | + -+ + + | Warning | 1264 | Out of range value for column ’sm1’ at row | + -+ + + row in set (0.00 sec) mysql> SELECT sm1 FROM sql_mode_test; + -+ | sm1 | + -+ | 126 | | 127 | | 127 | + -+ rows in set (0.00 sec) The inserted value that was too large for the field was truncated to the closest value that did fit in the field Similarly, for string data, strings get truncated if they are too large This behavior may or may not be desired; if it is not desired, set the appropriate sql_mode to throw an error: mysql> SET SESSION sql_mode=’TRADITIONAL’; Query OK, rows affected (0.00 sec) mysql> TRUNCATE sql_mode_test; Query OK, rows affected (0.42 sec) mysql> INSERT INTO sql_mode_test (sm1) VALUES (126); Query OK, row affected (0.08 sec) mysql> INSERT INTO sql_mode_test (sm1) VALUES (127); Query OK, row affected (0.09 sec) 202 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types mysql> INSERT INTO sql_mode_test (sm1) VALUES (128); ERROR 1264 (22003): Out of range value for column ’sm1’ at row mysql> SELECT sm1 FROM sql_mode_test; + -+ | sm1 | + -+ | 126 | | 127 | + -+ rows in set (0.00 sec) SQL modes Some values of sql_mode perform similar functions to each other, such as STRICT_ALL_ TABLES and STRICT_TRANS_TABLES Others can interact differently, for example ERROR_FOR_DIVISION_BY_ZERO causes division (or modulus) by zero to result in invalid data — if this data is used as an input value to a table and a strict sql_mode is used, an error will arise If this data is used as an input value to a table and there is no strict sql_mode used, a warning will arise and truncation will occur with a warning Some values of sql_mode are shorter ways to specify a certain set of sql_mode values SQL mode functionality The values of sql_mode can be grouped into their approximate functions: ■ Getting rid of silent failures, silent conversions, and silently allowing invalid data: ■ ALLOW_INVALID_DATES ■ ERROR_FOR_DIVISION_BY_ZERO ■ NO_AUTO_CREATE_USER ■ NO_AUTO_VALUE_ON_ZERO ■ NO_ENGINE_SUBSTITUTION ■ NO_ZERO_DATE ■ NO_ZERO_IN_DATE ■ STRICT_ALL_TABLES ■ STRICT_TRANS_TABLES ■ Other changes to default behavior: ■ HIGH_NOT_PRECEDENCE ■ IGNORE_SPACE ■ NO_BACKSLASH_ESCAPES ■ NO_DIR_IN_CREATE ■ PAD_CHAR_TO_FULL_LENGTH Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 203 Part II Developing with MySQL ■ Portability: ■ ANSI QUOTES ■ NO_FIELD_OPTIONS ■ NO_KEY_OPTIONS ■ NO_TABLE_OPTIONS ■ NO_UNSIGNED_SUBTRACTION ■ ONLY_FULL_GROUP_BY ■ PIPES_AS_CONCAT ■ REAL_AS_FLOAT ■ Act like other database systems: ■ ANSI ■ DB2 ■ MAXDB ■ MSSQL ■ MYSQL323 ■ MYSQL40 ■ ORACLE ■ POSTGRESQL ■ TRADITIONAL SQL mode definitions ■ ALLOW_INVALID_DATES — Any date in a DATETIME or DATE data type is allowed, provided the month is between and 12 and the day is between and 31 Invalid dates such as February 30th and September 31st are allowed — recall that invalid date insertion will throw an error if a strict sql_mode is used, otherwise it will insert a zero date ■ ANSI — Syntax and behavior closely match the SQL standard Equivalent to setting the sql_mode to ’REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE’ The ansi option to mysqld sets the global sql_mode to ANSI and changes the transaction isolation level to SERIALIZABLE ■ ANSI QUOTES — A double quote (") is now treated as an identifier quote (`) Strings can only be quoted with a single quote (’) ■ DB2 — Syntax and behavior closely match that of IBM’s DB2 database Equivalent to setting the sql_mode to ’PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_KEY_ OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS’ ■ ERROR_FOR_DIVISION_BY_ZERO — Division or modulo functions return NULL with no warning if this sql_mode is not set If this sql_mode is set, the return value is NULL with a warning: 204 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types mysql> SET SESSION sql_mode=’’; Query OK, rows affected (0.00 sec) mysql> select 1/0; + + | 1/0 | + + | NULL | + + row in set (0.05 sec) mysql> SET SESSION sql_mode=’ERROR_FOR_DIVISION_BY_ZERO’; Query OK, rows affected (0.00 sec) mysql> select 1/0; + + | 1/0 | + + | NULL | + + row in set, warning (0.00 sec) mysql> SHOW WARNINGS; + -+ + -+ | Level | Code | Message | + -+ + -+ | Error | 1365 | Division by | + -+ + -+ row in set (0.00 sec) Combined with a strict sql_mode, the INSERT and UPDATE operations will throw an error when trying to update data with this type of expression Note that INSERT IGNORE and UPDATE IGNORE will ignore an update with this type of expression and merely issue a warning, even with a strict sql_mode enabled ■ HIGH_NOT_PRECEDENCE — Without this sql_mode set, the NOT operator has a higher precedence than some operators, such as AND and OR, but has a lower precedence than other operators, such as BETWEEN and LIKE You can see the complete precedence list in Appendix B ■ When HIGH_NOT_PRECEDENCE is set in the sql_mode, the NOT operator takes a higher precedence For example, the expression NOT BETWEEN -5 AND is parsed using regular precedence rules as NOT (1 BETWEEN -5 AND 5) This is equivalent to NOT (true), which evaluates to ■ With the sql_mode of HIGH_NOT_PRECEDENCE set, the expression NOT BETWEEN -5 AND is parsed as (NOT 1) BETWEEN -5 AND This is equivalent to BETWEEN -5 AND 5, which evaluates to Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 205 Part II Developing with MySQL ■ IGNORE_SPACE — This sql_mode allows a space between a built-in function and the open parenthesis For example, with this sql_mode, both COUNT (*) and COUNT(*) are valid This means that built-in functions are now treated as reserved words, and must be escaped with an identifier quote (the backtick [`] character, or double quotes [‘‘] if an sql_mode of ANSI_QUOTES is also set) User-defined functions or stored functions are not affected by IGNORE_SPACE; they not need to be, because they always ignore spaces between the function name and the open parenthesis ■ MAXDB — Syntax and behavior closely matches SAP’s MaxDB Equivalent to setting the sql_mode to ’PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_ USER’, and makes TIMESTAMP an alias for DATETIME ■ MSSQL — Syntax and behavior closely matches Microsoft’s SQL Server Equivalent to setting the sql_mode to ’PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS’ ■ MYSQL323 — Syntax and behavior closely matches MySQL version 3.23 Equivalent to setting the sql_mode to ’NO_FIELD_OPTIONS, HIGH_NOT_PRECEDENCE’ ■ MYSQL40 — Syntax and behavior closely matches MySQL version 4.0 Equivalent to setting the sql_mode to ’NO_FIELD_OPTIONS, HIGH_NOT_PRECEDENCE’ ■ NO_AUTO_CREATE_USER — With this sql_mode set, a GRANT statement only creates a new user automatically if a non-empty password is specified If this sql_mode is not set, a GRANT statement will create a new user if the specified user does not exist, and allow passwordless login for that user (effectively gives that user a password of ") ■ NO_AUTO_VALUE_ON_ZERO — A numeric data type field with the AUTO_INCREMENT property will issue the next number in the sequence if or NULL is inserted With this sql_mode set, inserting a value of will actually insert into the field, and only a NULL value will result in the next sequential number being inserted into the field ■ NO_BACKSLASH_ESCAPES — If this sql_mode is set, the backslash (\) becomes an ordinary character, instead of a character that can be used to escape other characters ■ NO_DIR_IN_CREATE — The directories for the data and index files for a non-partitioned MyISAM table can be specified during table creation time with the DATA DIRECTORY and INDEX DIRECTORY options to CREATE TABLE This sql_mode ignores those options, which may be desired on a slave server ■ NO_ENGINE_SUBSTITUTION — If this sql_mode is set, an ALTER TABLE or CREATE TABLE statement that specifies a disabled or unavailable storage engine throws an error If this sql_mode is not set, such an ALTER TABLE statement would not change the table and a warning would be thrown; a similar CREATE TABLE statement would create a table with the default storage engine type and throw a warning ■ NO_FIELD_OPTIONS — If this sql_mode is set, the output of SHOW CREATE TABLE will not show MySQL-specific field definition options and properties 206 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types ■ NO_KEY_OPTIONS — If this sql_mode is set, the output of SHOW CREATE TABLE will not show MySQL-specific index options and properties ■ NO_TABLE_OPTIONS — If this sql_mode is set, the output of SHOW CREATE TABLE will not show MySQL-specific table options and properties ■ NO_UNSIGNED_SUBTRACTION — If this sql_mode is set, the result of a subtraction is always a signed numeric value If this sql_mode is not set, the result of a subtraction is an unsigned numeric value if one of the operands is unsigned Due to the different ranges of SIGNED and UNSIGNED integer data types (see Table 5-3), subtraction with an UNSIGNED BIGINT operand may not obtain the desired results: mysql> SET SESSION SQL_MODE=’’; Query OK, rows affected (0.00 sec) mysql> SELECT CAST(0 AS UNSIGNED) - 1; + -+ | CAST(0 AS UNSIGNED) - | + -+ | 18446744073709551615 | + -+ row in set (0.00 sec) mysql> SET SESSION SQL_MODE=’NO_UNSIGNED_SUBTRACTION’; Query OK, rows affected (0.00 sec) mysql> SELECT CAST(0 AS UNSIGNED) - 1; + -+ | CAST(0 AS UNSIGNED) - | + -+ | -1 | + -+ row in set (0.00 sec) ■ NO_ZERO_DATE — If this sql_mode is not set, a warning is generated if a date field has a zero date (’0000-00-00’) inserted or updated A warning will also be issued if this sql_mode is set and a strict sql_mode is also set, and INSERT IGNORE or UPDATE IGNORE is used to change the date field to a zero date Otherwise, if this sql_mode is set and a strict sql_mode is also set, a zero date insertion or update will be rejected with an error ■ NO_ZERO_IN_DATE — If this sql_mode is not set, partial or total zero dates are allowed: mysql> USE test; Database changed mysql> SET SESSION SQL_MODE=’’; Query OK, rows affected (0.00 sec) mysql> CREATE TABLE date_zero_test (dt1 char(10) DEFAULT NULL, -> dt2 date DEFAULT NULL); Query OK, rows affected (0.00 sec) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 207 Part II Developing with MySQL mysql> INSERT INTO date_zero_test (dt1, dt2) VALUES -> (’2012-11-25’,’2012-11-25’),(’2012-11-00’,’2012-11-00’), -> (’2012-00-25’,’2012-00-25’),(’2012-00-00’,’2012-00-00’), -> (’0000-11-25’,’0000-11-25’),(’0000-11-00’,’0000-11-00’), -> (’0000-00-25’,’0000-00-25’),(’0000-00-00’,’0000-00-00’); Records: Duplicates: Warnings: mysql> SELECT dt1, dt2 FROM date_zero_test; + + + | dt1 | dt2 | + + + | 2012-11-25 | 2012-11-25 | | 2012-11-00 | 2012-11-00 | | 2012-00-25 | 2012-00-25 | | 2012-00-00 | 2012-00-00 | | 0000-11-25 | 0000-11-25 | | 0000-11-00 | 0000-11-00 | | 0000-00-25 | 0000-00-25 | | 0000-00-00 | 0000-00-00 | + + + rows in set (0.00 sec) If this sql_mode is set, a warning is generated and a zero date is inserted if an INSERT or UPDATE on a date field tries to use a date with a non-zero year part and a zero month or a zero day part (that is, ’2009-11-00’ or ’2009-00-20’) mysql> TRUNCATE date_zero_test; Query OK, rows affected (0.00 sec) mysql> SET SESSION sql_mode=’NO_ZERO_IN_DATE’; Query OK, rows affected (0.00 sec) mysql> INSERT INTO date_zero_test (dt1, dt2) VALUES -> (’2012-11-25’,’2012-11-25’),(’2012-11-00’,’2012-11-00’), -> (’2012-00-25’,’2012-00-25’),(’2012-00-00’,’2012-00-00’), -> (’0000-11-25’,’0000-11-25’),(’0000-11-00’,’0000-11-00’), -> (’0000-00-25’,’0000-00-25’),(’0000-00-00’,’0000-00-00’); Query OK, rows affected, warnings (0.00 sec) Records: Duplicates: Warnings: mysql> SHOW WARNINGS; + -+ + + | Level | Code | Message | + -+ + + | Warning | 1265 | Data truncated for column ’dt2’ at row | | Warning | 1265 | Data truncated for column ’dt2’ at row | | Warning | 1265 | Data truncated for column ’dt2’ at row | | Warning | 1265 | Data truncated for column ’dt2’ at row | | Warning | 1265 | Data truncated for column ’dt2’ at row | + -+ + + rows in set (0.00 sec) 208 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types mysql> SELECT dt1, dt2 FROM date_zero_test; + + + | dt1 | dt2 | + + + | 2012-11-25 | 2012-11-25 | | 2012-11-00 | 0000-00-00 | | 2012-00-25 | 0000-00-00 | | 2012-00-00 | 0000-00-00 | | 0000-11-25 | 0000-11-25 | | 0000-11-00 | 0000-00-00 | | 0000-00-25 | 0000-00-00 | | 0000-00-00 | 0000-00-00 | + + + rows in set (0.00 sec) A warning will also be issued and a zero date (0000-00-00) is used if this sql_mode is set and a strict sql_mode is also set, and INSERT IGNORE or UPDATE IGNORE is used to change the date field to a date with a non-zero part Otherwise, if this sql_mode is set and a strict sql_mode is also set, a zero date insertion or update will be rejected with an error: mysql> TRUNCATE date_zero_test; Query OK, rows affected (0.00 sec) mysql> SET SESSION sql_mode=’NO_ZERO_IN_DATE,STRICT_ALL_TABLES’; Query OK, rows affected (0.00 sec) mysql> INSERT INTO date_zero_test (dt1, dt2) VALUES -> (’2012-11-25’,’2012-11-25’),(’2012-11-00’,’2012-11-00’), -> (’2012-00-25’,’2012-00-25’),(’2012-00-00’,’2012-00-00’), -> (’0000-11-25’,’0000-11-25’),(’0000-11-00’,’0000-11-00’), -> (’0000-00-25’,’0000-00-25’),(’0000-00-00’,’0000-00-00’);ERROR 1292 (22007): Incorrect date value: ’2012-11-00’ for column ’dt2’ at row mysql> SELECT dt1, dt2 FROM date_zero_test; + + + | dt1 | dt2 | + + + | 2012-11-25 | 2012-11-25 | + + + row in set (0.00 sec) ■ ONLY_FULL_GROUP_BY — When this sql_mode is set, a GROUP BY query requires the fields in the SELECT and HAVING clauses to contain only aggregated fields and the fields in the GROUP BY clause That is, no fields can appear in the SELECT or HAVING clauses unless they are either in the GROUP BY clause or an aggregation of fields mysql> SET SESSION sql_mode=’’; Query OK, rows affected (0.00 sec) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 209 Part II Developing with MySQL mysql> USE sakila; Database changed mysql> SELECT AVG(length),rental_duration,title FROM film GROUP BY rental_duration; + -+ -+ + | AVG(length) | rental_duration | title | + -+ -+ + | 112.9113 | | ACE GOLDFINGER | | 111.2315 | | ALI FOREVER | | 116.5602 | | AFFAIR PREJUDICE | | 117.0377 | | ACADEMY DINOSAUR | | 118.8272 | | ADAPTATION HOLES | + -+ -+ + rows in set (0.00 sec) mysql> SET SESSION sql_mode=’ONLY_FULL_GROUP_BY’; Query OK, rows affected (0.03 sec) mysql> SELECT AVG(length),rental_duration,title FROM film GROUP BY rental_duration; ERROR 1055 (42000): ’sakila.film.title’ isn’t in GROUP BY ■ ORACLE — Syntax and behavior closely matches Oracle Equivalent to setting the sql_mode to ’PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_KEY_OPTIONS, NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER’ ■ PAD_CHAR_TO_FULL_LENGTH — If this sql_mode is set, the behavior of retrieving a fixed-width string from a table is changed See the note in the subsection on CHAR length earlier in this chapter ■ PIPES_AS_CONCAT — When this sql_mode is not set, || is an alias for OR When this sql_mode is set, || is a string concatenation operator ■ POSTGRESQL — Syntax and behavior closely matches Postgresql Equivalent to setting the sql_mode to ’PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS’ ■ REAL_AS_FLOAT — When this sql_mode is not set, REAL is an alias for DOUBLE When this sql_mode is set, REAL is an alias for FLOAT ■ STRICT_ALL_TABLES — When this sql_mode is not set, invalid data values are allowed, usually converted to valid data by using zero values or truncating the value When this sql_mode is set, invalid data values are rejected, and an error is thrown If there are multiple values in an insert or update to a non-transactional table, the updates prior to the error are completed even though the statement itself throws an error If the sql_mode of STRICT_ALL_TABLES is set, the behavior of allowing invalid data and throwing a warning can be accomplished by using INSERT IGNORE and UPDATE IGNORE ■ STRICT_TRANS_TABLES — When this sql_mode is not set, invalid data values are allowed, usually converted to valid data by using zero values or truncating the value 210 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types When this sql_mode is set, invalid data values in a transactional table are rejected, and an error is thrown For invalid data inserted or updated to non-transactional tables, invalid data values are truncated or converted to zero values If the sql_mode of STRICT_TRANS_TABLES is set, the behavior of allowing invalid data in transactional tables and throwing a warning can be accomplished by using INSERT IGNORE and UPDATE IGNORE ■ TRADITIONAL — Syntax and behavior closely match traditional expectations Equivalent to setting the sql_mode to ’STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER’ Using NULL Values Allowing NULL values in data types should be done only with some forethought Many properties of NULL make it undesirable: ■ A field that allows NULL values (that is, is not specified with NOT NULL) uses more storage space and more resources to process storage, retrieval, comparisons, and calculations The empty string (’’), and zero values such as and 0000-00-00 use less space than NULL ■ Most operators and functions are not NULL-safe, and will return NULL if there is at least one NULL value used For example, the following all return NULL: SELECT SELECT SELECT SELECT SELECT 1+NULL; CONCAT(’foo’,NULL); NULL=NULL; NULL SELECT count(title) FROM film; + + | count(title) | + + | 1000 | + + row in set (0.00 sec) 212 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types mysql> SELECT title FROM film PROCEDURE ANALYSE(16,256)\G *************************** row *************************** Field_name: sakila.film.title Min_value: ACADEMY DINOSAUR Max_value: ZORRO ARK Min_length: Max_length: 27 Empties_or_zeros: Nulls: Avg_value_or_avg_length: 14.2350 Std: NULL Optimal_fieldtype: VARCHAR(27) NOT NULL row in set (0.00 sec) The first field returned, Field_name, is the name of the field that this row is analyzing The next four fields give the minimum and maximum values and lengths The Empties_or_zeros field reports on how many records have an empty value (’’) or a zero value for this field, and the Nulls field reports on how many records have a NULL value for this field The Avg_value_or_avg_length field is self-explanatory, providing the average value for a numeric data type and the average length for a character or string data type The Std field gives the standard deviation, which is the same as running SELECT STDDEV(fld), and is NULL for non-numeric types The Optimal_fieldtype field reveals the optimal data type for the field according to the analysis In this case, because there are no NULL values, and the maximum length is 27, the Optimal_fieldtype is VARCHAR(27) NOT NULL This is a good starting point for a discussion about what the field should be — there are 1,000 titles, and the longest among them is 27, with the average length being slightly more than half the maximum length The recommendation of VARCHAR(27) NOT NULL will fit the current data exactly Knowing that the longest value so far is 27 helps to limit the possible range; however, there may be a longer film title in the future — maybe 28 characters, or 30 characters Take a look at the longest title: mysql> SELECT title FROM film WHERE LENGTH(title)=27; + -+ | title | + -+ | ARACHNOPHOBIA ROLLERCOASTER | + -+ row in set (0.01 sec) Given the title of the longest film, you may want to at least add two characters so that a sequel can be made entitled ARACHNOPHOBIA ROLLERCOASTER Based on reasoning such as this, you may decide to change the data type of title to VARCHAR(35) NOT NULL This does not have to be exact; recall that title started out as VARCHAR(255) NOT NULL, so even changing it to VARCHAR(50) NOT NULL saves a lot of space Changing the data type of a field requires doing Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 213 Part II Developing with MySQL an ALTER TABLE statement, which locks the whole table for the duration of the change, so it is better to start with a good estimate, and re-evaluate once the real data set gets large enough to be useful, but not so large that changing a data type will take an unacceptably long time In the sakila.payment table, the amount field is defined as: `amount` decimal(5,2) NOT NULL This is a sensible amount, because it is not likely that a payment to a video store will be more than 999.99, and it is also unlikely that a refund will result in a payment amount less than –999.99 In this case, PROCEDURE ANALYSE() shows us: mysql> SELECT COUNT(amount) FROM payment; + -+ | COUNT(amount) | + -+ | 16049 | + -+ row in set (0.01 sec) mysql> SELECT amount FROM payment PROCEDURE ANALYSE(16)\G *************************** row *************************** Field_name: sakila.payment.amount Min_value: 0.99 Max_value: 11.99 Min_length: Max_length: 14 Empties_or_zeros: 24 Nulls: Avg_value_or_avg_length: 4.200667 Std: 2.362920 Optimal_fieldtype: DECIMAL(13, 2) NOT NULL row in set (0.01 sec) This output is somewhat misleading, because the Min_length and Max_length fields not seem to have any relation to either the size or length of the field The Optimal_fieldtype seems to be using the Max_length value when determining its recommendation This is actually an artifact; the internal storage format of DECIMAL changed in MySQL 5.0, and the PROCEDURE ANALYSE() function was never updated, so the calculations are off You can avoid problems by thinking about whether the output makes sense, and not necessarily depending on only the Optimal_fieldtype field for the recommended data type Examine all the information before making a conclusion In this case, concentrate on the maximum and minimum amounts, and note that the actual payment amounts are much smaller than the maximum allowed value of 999.99 There are more than 16,000 payments, so this data is a good sample size It is also notable that there are no negative values in the payments table This suggests that refunds are handled separately, suggesting an UNSIGNED data type might be appropriate 214 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types Looking at the schema for the payment table, each amount is associated with a rental_id, which is a foreign key to the rental table The rental table associates a rental_id with a single inventory_id This means that each payment is based on the amount paid for one movie rental Given this information, an optimal field might be DECIMAL(4,2) UNSIGNED NOT NULL, corresponding to the facts that the payment table only holds payments (not refunds), movie rentals cost anywhere from (free) to 99.99, a payment (really, a record in the payment table) will always have a known value for the amount field, and that the maximum required precision of currency is 0.01 Small data samples and PROCEDURE ANALYSE() The PROCEDURE ANALYSE() function needs a good sample size in order to present a good optimal data type For example, the sakila.staff table defines the first_name and last_name fields as: `first_name` varchar(45) NOT NULL `last_name` varchar(45) NOT NULL What does PROCEDURE ANALYSE() believe is the optimal data type for these fields? mysql> SELECT COUNT(first_name),COUNT(last_name) FROM staff; + -+ + | COUNT(first_name) | COUNT(last_name) | + -+ + | | | + -+ + row in set (0.00 sec) mysql> SELECT first_name, last_name -> FROM staff PROCEDURE ANALYSE(16)\G *************************** row *************************** Field_name: sakila.staff.first_name Min_value: Jon Max_value: Mike Min_length: Max_length: Empties_or_zeros: Nulls: Avg_value_or_avg_length: 3.5000 Std: NULL Optimal_fieldtype: ENUM(’Jon’,’Mike’) NOT NULL *************************** row *************************** Field_name: sakila.staff.last_name Min_value: Hillyer Max_value: Stephens Min_length: Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 215 Part II Developing with MySQL Max_length: Empties_or_zeros: Nulls: Avg_value_or_avg_length: Std: Optimal_fieldtype: rows in set (0.00 sec) 0 7.5000 NULL ENUM(’Hillyer’,’Stephens’) NOT NULL Because there are only two records to choose from, and an ENUM field can be the optimal data type so long as there are fewer than 16 strings in the enumerated list, an ENUM field was shown as the optimal data type for both first_name and last_name Obviously, this is a poor idea for fields with first and last names What happens when an ENUM field cannot be used at all? mysql> SELECT first_name, last_name FROM staff PROCEDURE ANALYSE(0)\G *************************** row *************************** Field_name: sakila.staff.first_name Min_value: Jon Max_value: Mike Min_length: Max_length: Empties_or_zeros: Nulls: Avg_value_or_avg_length: 3.5000 Std: NULL Optimal_fieldtype: CHAR(4) NOT NULL *************************** row *************************** Field_name: sakila.staff.last_name Min_value: Hillyer Max_value: Stephens Min_length: Max_length: Empties_or_zeros: Nulls: Avg_value_or_avg_length: 7.5000 Std: NULL Optimal_fieldtype: CHAR(8) NOT NULL rows in set (0.00 sec) Again, the sample set is too small to get a reasonable data type The data type CHAR(4) for a first name is way too small; neither of the authors of this book (‘‘Keith’’ has a length of and ‘‘Sheeri’’ has a length of 6) would have their first name able to fit in such a field! PROCEDURE ANALYSE() is an excellent tool to pare down existing data; however, care should be taken so that an ENUM field is not always listed, and that there is a big enough sample data size to justify an optimal data type returned Even then, the information returned by PROCEDURE ANALYSE() should be used to make an informed decision on an optimal data type for a field 216 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark ... set (0.00 sec) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 177 Part II Developing with MySQL mysql> USE sakila; Database changed mysql> SHOW CREATE TABLE category\G... field: 198 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MySQL Data Types mysql> SET SESSION sql_mode=’’; Query OK, rows affected (0.00 sec) mysql> CREATE TABLE enum_set_test... to ’’: mysql> SET SESSION sql_mode=’’; Query OK, rows affected (0.00 sec) Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 201 Part II Developing with MySQL mysql>

Ngày đăng: 24/12/2013, 17:15

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan