@wxy
This commit is contained in:
Xingyu Wang 2023-01-11 11:37:46 +08:00
parent 2de0fbbc12
commit 328b0ddcc3
2 changed files with 230 additions and 228 deletions

View File

@ -1,228 +0,0 @@
[#]: subject: "A guide to strings in MySQL"
[#]: via: "https://opensource.com/article/23/1/strings-mysql"
[#]: author: "Hunter Coleman https://opensource.com/users/hunterc"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
A guide to strings in MySQL
======
Strings are one of the most common data types you will use in MySQL. Many users insert and read strings in their databases without thinking too much about them. This article aims to give you a bit of a deep dive into how MySQL stores and displays your string variables so that you can have better control over your data.
You can break strings into two categories: binary and nonbinary. You probably think about nonbinary strings most of the time. Nonbinary strings have character sets and collations. Binary strings, on the other hand, store things such as MP3 files or images. Even if you store a word in a binary string, such as **song**, it is not stored in the same way as in a nonbinary string.
I will focus on nonbinary strings. All nonbinary strings in MySQL are associated with a character set and a collation. A string's character set controls what characters can be stored in the string, and its collation controls how the strings are ordered when you display them.
### Character sets
To view the character sets on your system, run the following command:
```
SHOW CHARACTER SET;
```
This command will output four columns of data, including the character set:
- Name
- Brief description
- Default collation
- Maximum size of each character in the character set
MySQL used to default to the **latin1** character set, but since version 8.0, the default has been **utf8mb4**. The default collation is now **utf8mb4_0900_ai_ci**. The **ai** indicates that this collation is accent insensitive (**á = a**), and the **ci** specifies that it is case insensitive (**a = A**).
Different character sets store their characters in various-sized chunks of memory. For example, as you can see from the above command, characters stored in **utf8mb4** are stored in memory from one to four bytes in size. If you want to see if a string has multibyte characters, you can use the **CHAR_LENGTH()** and **LENGTH()** functions. **CHAR_LENGTH()** displays how many characters a string contains, whereas **LENGTH()** shows how many bytes a string has, which may or may not be the same as a string's length in characters, depending on the character set. Here is an example:
```
SET @a = CONVERT('data' USING latin1);
SELECT LENGTH(@a), CHAR_LENGTH(@a);
+------------+-----------------+
| LENGTH(@a) | CHAR_LENGTH(@a) |
+------------+-----------------+
| 4 | 4 |
+------------+-----------------+
```
This example shows that the **latin1** character set stores characters in single-byte units. Other character sets, such as **utf16**, allow multibyte characters:
```
SET @b = CONVERT('data' USING utf16);
SELECT LENGTH(@b), CHAR_LENGTH(@b);
+------------+------------------+
| LENGTH(@b) | CHAR_LENGTH(@b) |
+------------+------------------+
| 8 | 4 |
+------------+------------------+
```
### Collation
A string's collation will determine how the values are displayed when you run a SQL statement with an **ORDER BY** clause. Your choice of collations is determined by what character set you select. When you ran the command `SHOW CHARACTER SET` above, you saw the default collations for each character set. You can easily see all the collations available for a particular character set. For example, if you want to see which collations are allowed by the **utf8mb4** character set, run:
```
SHOW COLLATION LIKE 'utf8mb4%';
```
A collation can be case-insensitive, case-sensitive, or binary. Let's build a simple table, insert a few values into it, and then view the data using different collations to see how the output differs:
```
CREATE TABLE sample (s CHAR(5));
INSERT INTO sample (s) VALUES
('AAAAA'), ('ccccc'), ('bbbbb'), ('BBBBB'), ('aaaaa'), ('CCCCC');
SELECT * FROM sample;
+-----------+
| s |
+-----------+
| AAAAA |
| ccccc |
| bbbbb |
| BBBBB |
| aaaaa |
| CCCCC |
+-----------+
```
With case-insensitive collations, your data is returned in alphabetical order, but there is no guarantee that capitalized words will come before lowercase words, as seen below:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_turkish_ci;
+-----------+
| s |
+-----------+
| AAAAA |
| aaaaa |
| bbbbb |
| BBBBB |
| ccccc |
| CCCCC |
+-----------+
```
On the other hand, when MySQL runs a case-sensitive search, lowercase will come before uppercase for each letter:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_0900_as_cs;
+-----------+
| s |
+-----------+
| aaaaa |
| AAAAA |
| bbbbb |
| BBBBB |
| ccccc |
| CCCCC |
+-----------+
```
And binary collations will return all capitalized words before lowercase words:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_0900_bin;
+-----------+
| s |
+-----------+
| AAAAA |
| ccccc |
| bbbbb |
| BBBBB |
| aaaaa |
| CCCCC |
+-----------+
```
If you want to know which character set and collation a string uses, you can use the aptly named **charset** and **collation** functions. A server running MySQL version 8.0 or higher will default to using the **utf8mb4** character set and **utf8mb4_0900_ai-ci** collation:
```
SELECT charset('data');
+-------------------+
| charset('data') |
+-------------------+
| utf8mb4 |
+-------------------+
SELECT collation('data');
+--------------------+
| collation('data') |
+--------------------+
| utf8mb4_0900_ai_ci |
+--------------------+
```
You can use the `SET NAMES` command to change the character set or collation used.
To change from the **utf8mb4** character set to **utf16**, run this command:
```
SET NAMES 'utf16';
```
If you would also like to choose a collation other than the default, you can add a **COLLATE** clause to the `SET NAMES` command.
For example, say your database stores words in the Spanish language. The default collation for MySQL (**utf8mb4_0900_ai_ci**) sees ch and ll as two different characters and will sort them as such. But in Spanish, ch and ll are individual letters, so if you want them sorted in the proper order (following c and l, respectively), you need to use a different collation. One option is to use the **utf8mb4_spanish2_ci** collation.
```
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_spanish2-ci';
```
### Storing strings
MySQL allows you to choose between several data types for your string values. (Even more so than other popular databases such as PostgreSQL and MongoDB.)
Here is a list of MySQL's binary string data types, their nonbinary equivalents, and their maximum length:
- **binary:** char (255)
- **varbinary:** varchar (65,535)
- **tinyblob:** tinytext (255)
- **blob:** text (65,535)
- **mediumblob:** mediumtext (16,777,215)
- **longblob:** longtext (4,294,967,295)
One important thing to remember is that unlike the varbinary, varchar, text, and blob types, which are stored in variable length fields (that is, using only as much space as needed), MySQL stores binary and char types in fixed length fields. So a value such as **char(20)** or **binary(20)** will always take up 20 bytes, even if you store less than 20 characters in them. MySQL pads the values with the **ASCII NUL** value (**0x00**) for binary types and spaces for char types.
Another thing to consider when choosing data types is whether you want spaces after the string to be preserved or stripped. When displaying data, MySQL strips whitespace from data stored with the char data type, but not varchar.
```
CREATE TABLE sample2 (s1 CHAR(10), s2 VARCHAR(10));
INSERT INTO sample2 (s1, s2) VALUES ('cat ', 'cat ');
SELECT s1, s2, CHAR_LENGTH(s1), CHAR_LENGTH(s2) FROM sample2;
+---------+---------+-----------------------------------+
| s1 | s2 | CHAR_LENGTH(s1) | CHAR_LENGTH(s2) |
+---------+---------+-----------------------------------+
| cat | cat | 3 | 10 |
+---------+---------+-----------------------------------+
```
### Wrap up
Strings are one of the most common data types used in databases, and MySQL remains one of the most popular database systems in use today. I hope that you have learned something new from this article and will be able to use your new knowledge to improve your database skills.
--------------------------------------------------------------------------------
via: https://opensource.com/article/23/1/strings-mysql
作者:[Hunter Coleman][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/hunterc
[b]: https://github.com/lkxed

View File

@ -0,0 +1,230 @@
[#]: subject: "A guide to strings in MySQL"
[#]: via: "https://opensource.com/article/23/1/strings-mysql"
[#]: author: "Hunter Coleman https://opensource.com/users/hunterc"
[#]: collector: "lkxed"
[#]: translator: "wxy"
[#]: reviewer: "wxy"
[#]: publisher: " "
[#]: url: " "
MySQL 字符串指南
======
> 了解 MySQL 如何存储和显示你的字符串变量,以便你能更好地控制你的数据。
字符串是你在 MySQL 中使用的最常见的数据类型之一。许多用户在他们的数据库中插入和读取字符串,而没有认真地了解过它们。本文旨在让你深入了解 MySQL 如何存储和显示你的字符串变量,以便你能更好地控制你的数据。
你可以把字符串分成两类:二进制和非二进制。你可能在大多数时候想到的是非二进制字符串。非二进制字符串有字符集和排序的不同。另一方面,二进制字符串存储诸如 MP3 文件或图像等东西。即使你在二进制字符串中存储了一个词,比如“歌曲”,它的存储方式也与非二进制字符串不同。
我将重点讨论非二进制字符串。MySQL 中的所有非二进制字符串都与字符集和排序相关。字符串的字符集控制哪些字符可以存储在字符串中,而它的排序方式控制当你显示字符串时如何排序。
### 字符集
要查看你系统中的字符集,请运行以下命令:
```
SHOW CHARACTER SET;
```
这个命令将输出四列数据,包括字符集:
- 名称
- 简要描述
- 默认的排序方式
- 字符集中每个字符的最大尺寸
MySQL 过去默认为 `latin1` 字符集,但自 8.0 版以来,默认为 `utf8mb4`。现在的默认排序方式是 `utf8mb4_0900_ai_ci`。`ai` 表示该排序对音调不敏感( `á` = `a`),而 `ci` 则指定它对大小写不敏感(`a` = `A`)。
不同的字符集将其字符存储在内存中不同大小的块中。例如,从上面的命令可以看出,存储在 `utf8mb4` 的字符被存储在 1 到 4 个字节大小的内存中。如果你想看看一个字符串是否包含多字节的字符,你可以使用 `CHAR_LENGTH()``LENGTH()` 函数。`CHAR_LENGTH()` 显示一个字符串包含多少个字符,而 `LENGTH()` 显示一个字符串有多少个字节,根据字符集的不同,它可能与一个字符串的字符长度相同,也可能不相同。下面是一个例子:
```
SET @a = CONVERT('data' USING latin1);
SELECT LENGTH(@a), CHAR_LENGTH(@a);
+------------+-----------------+
| LENGTH(@a) | CHAR_LENGTH(@a) |
+------------+-----------------+
| 4 | 4 |
+------------+-----------------+
```
这个例子表明,`latin1` 字符集以单字节为单位存储字符。其他字符集,如 `utf16`,允许多字节的字符:
```
SET @b = CONVERT('data' USING utf16);
SELECT LENGTH(@b), CHAR_LENGTH(@b);
+------------+------------------+
| LENGTH(@b) | CHAR_LENGTH(@b) |
+------------+------------------+
| 8 | 4 |
+------------+------------------+
```
### 排序
当你运行带有 `ORDER BY` 子句的 SQL 语句时,字符串排序方式将决定值的显示方式。你对排序方式的选择是由你选择的字符集决定的。当你运行上面的 `SHOW CHARACTER SET` 命令时,你看到了每个字符集的默认排序方式。你可以很容易地看到某个特定字符集的所有排序方式。例如,如果你想查看 `utf8mb4` 字符集允许哪些排序,请运行:
```
SHOW COLLATION LIKE 'utf8mb4%';
```
排序方式可以是不区分大小写的,也可以是区分大小写的,或者是二进制的。让我们建立一个简单的表,向其中插入一些值,然后用不同的排序方式查看数据,看看输出结果有什么不同:
```
CREATE TABLE sample (s CHAR(5));
INSERT INTO sample (s) VALUES
('AAAAA'), ('ccccc'), ('bbbbb'), ('BBBBB'), ('aaaaa'), ('CCCCC');
SELECT * FROM sample;
+-----------+
| s |
+-----------+
| AAAAA |
| ccccc |
| bbbbb |
| BBBBB |
| aaaaa |
| CCCCC |
+-----------+
```
在不区分大小写的情况下,你的数据会按字母顺序返回,但不能保证大写的单词会排在小写的单词之前,如下图所示:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_turkish_ci;
+-----------+
| s |
+-----------+
| AAAAA |
| aaaaa |
| bbbbb |
| BBBBB |
| ccccc |
| CCCCC |
+-----------+
```
另一方面,当 MySQL 运行大小写敏感的搜索时,每个字母的小写将排在大写之前:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_0900_as_cs;
+-----------+
| s |
+-----------+
| aaaaa |
| AAAAA |
| bbbbb |
| BBBBB |
| ccccc |
| CCCCC |
+-----------+
```
而按二进制排序方式将返回所有大写的值,然后再返回小写的值:
```
SELECT * FROM sample ORDER BY s COLLATE utf8mb4_0900_bin;
+-----------+
| s |
+-----------+
| AAAAA |
| ccccc |
| bbbbb |
| BBBBB |
| aaaaa |
| CCCCC |
+-----------+
```
如果你想知道一个字符串使用哪种字符集和排序,你可以使用被恰当命名的 `charset``collation` 函数。运行 MySQL 8.0 或更高版本的服务器将默认使用 `utf8mb4` 字符集和 `utf8mb4_0900_ai_ci` 排序:
```
SELECT charset('data');
+-------------------+
| charset('data') |
+-------------------+
| utf8mb4 |
+-------------------+
SELECT collation('data');
+--------------------+
| collation('data') |
+--------------------+
| utf8mb4_0900_ai_ci |
+--------------------+
```
你可以使用 `SET NAMES` 命令来改变所使用的字符集或排序方式。
要从 `utf8mb4` 字符集改为 `utf16`,运行这个命令:
```
SET NAMES 'utf16';
```
如果你想选择默认以外的排序方式,你可以在 `SET NAMES` 命令中添加一个 `COLLATE` 子句。
例如假设你的数据库存储西班牙语的单词。MySQL 的默认排序(`utf8mb4_0900_ai_ci`)将 `ch``ll` 视为两个不同的字符,并将它们排序。但在西班牙语中,`ch` 和 `ll` 是单独的字母,所以如果你想让它们按正确的顺序排序(分别排在 `c``l` 之后),你需要使用不同的排序。一个选择是使用 `utf8mb4_spanish2_ci` 排序方式:
```
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_spanish2_ci';
```
### 储存字符串
MySQL 允许你为你的字符串值选择不同的数据类型。(甚至比其他流行的数据库,如 PostgreSQL 和 MongoDB 更多。)
下面是 MySQL 的二进制字符串数据类型的列表、它们的非二进制对应物,以及它们的最大长度:
- `binary``char`255
- `varbinary``varchar`65,535
- `tinyblob``tinytext`255
- `blob``text`65,535
- `mediumblob``mediumtext`16,777,215
- `longblob``longtext`4,294,967,295
要记住的一件重要事情是,与被存储在可变长度的字段中的 `varbinary`、`varchar`、`text` 和 `blob` 类型不同也就是说只使用需要的空间MySQL 将二进制(`binary`)和字符(`char`)类型存储在固定长度的字段。因此,像 `char(20)``binary(20)` 这样的值将总是占用 20 个字节,即使你在其中存储了少于 20 个字符。对于二进制类型MySQL用 ASCII NUL 值(`0x00`)填充这些值,对于 字符类型,用空格填充。
在选择数据类型时要考虑的另一件事是你是否希望在字符串后面的空格被保留或剥离。在显示数据时MySQL 会从以字符数据类型存储的数据中剥离空格,但不会剥离 `varchar` 的空格。
```
CREATE TABLE sample2 (s1 CHAR(10), s2 VARCHAR(10));
INSERT INTO sample2 (s1, s2) VALUES ('cat ', 'cat ');
SELECT s1, s2, CHAR_LENGTH(s1), CHAR_LENGTH(s2) FROM sample2;
+---------+---------+-----------------------------------+
| s1 | s2 | CHAR_LENGTH(s1) | CHAR_LENGTH(s2) |
+---------+---------+-----------------------------------+
| cat | cat | 3 | 10 |
+---------+---------+-----------------------------------+
```
### 总结
字符串是数据库中最常用的数据类型之一,而 MySQL 仍然是当今最流行的数据库系统之一。我希望你能从这篇文章中学到一些新的东西,并能用你的新知识来提高你的数据库技能。
--------------------------------------------------------------------------------
via: https://opensource.com/article/23/1/strings-mysql
作者:[Hunter Coleman][a]
选题:[lkxed][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/hunterc
[b]: https://github.com/lkxed