## 模块 3: Hash 和 Key 分区表

+ 在本模块中，我们将创建一个 Hash 分区表和一个 Key 分区表。向两个表插入相同的数据后，我们将比较数据的分布情况。

### 步骤 1. 创建新的 Hash 分区表 `employees1`

   ```sql
   CREATE TABLE employees1(
      id INT NOT NULL,
      fname VARCHAR(30),
      lname VARCHAR(30),
      hired DATE NOT NULL DEFAULT '1970-01-01',
      job_code INT
   )
   PARTITION BY HASH(YEAR(hired))
   PARTITIONS 5;
   ```

   ```output
   Query OK, 0 rows affected (0.54 sec)
   ```

### 步骤 2. 向 `employees1` 插入一些数据

   ```sql
   INSERT INTO employees1 VALUES(1, 'Jim', 'Lee', '2023-04-04', 2);
   INSERT INTO employees1 VALUES(2, 'Tim', 'Anderson', '2023-05-10', 2);
   INSERT INTO employees1 VALUES(3, 'Mike', 'Jackson', '2023-05-10', 3);
   INSERT INTO employees1 VALUES(4, 'Benjamin', 'Thompson', '2023-09-24', 1);
   INSERT INTO employees1 VALUES(5, 'Charlotte', 'Clark', '2023-09-24', 1);
   ```

   ```output
   Query OK, 1 row affected (0.00 sec)
   ```

+ 我们发现插入的所有行的 YEAR(hired) 值都相同。让我们检查一下数据的分布情况。

   ```sql
   ANALYZE TABLE employees1;
   SELECT table_name, partition_name, partition_description, table_rows FROM information_schema.partitions WHERE table_schema = 'test' AND table_name='employees1'
   ORDER BY partition_name;
   ```

   ```outputs
   +------------+----------------+-----------------------+------------+
   | table_name | partition_name | partition_description | table_rows |
   +------------+----------------+-----------------------+------------+
   | employees1 | p0             |                       |          0 |
   | employees1 | p1             |                       |          0 |
   | employees1 | p2             |                       |          0 |
   | employees1 | p3             |                       |          5 |
   | employees1 | p4             |                       |          0 |
   +------------+----------------+-----------------------+------------+
   5 rows in set (0.01 sec)
   ```

+ 你可以看到所有行都存储在分区 `p3`中。为什么呢？现在让我们截断表 `employees1` 并再次插入 5 行新数据。

   ```sql
   TRUNCATE TABLE employees1;
   INSERT INTO employees1 VALUES(1, 'Jim', 'Lee', '2020-04-04', 2);
   INSERT INTO employees1 VALUES(2, 'Tim', 'Anderson', '2021-05-10', 2);
   INSERT INTO employees1 VALUES(3, 'Mike', 'Jackson', '2022-05-10', 3);
   INSERT INTO employees1 VALUES(4, 'Benjamin', 'Thompson', '2023-09-24', 1);
   INSERT INTO employees1 VALUES(5, 'Charlotte', 'Clark', '2024-09-24', 1);
   ```

   ```output
   Query OK, 1 row affected (0.01 sec)
   ```

+ 这次插入的所有行的 `YEAR(hired)` 值都不同。让我们检查一下数据的分布情况。

   ```sql
   ANALYZE TABLE employees1;
   SELECT table_name, partition_name, partition_description, table_rows FROM information_schema.partitions WHERE table_schema = 'test' AND table_name='employees1'
   ORDER BY partition_name;
   ```

   ```output
   +------------+----------------+-----------------------+------------+
   | table_name | partition_name | partition_description | table_rows |
   +------------+----------------+-----------------------+------------+
   | employees1 | p0             |                       |          1 |
   | employees1 | p1             |                       |          1 |
   | employees1 | p2             |                       |          1 |
   | employees1 | p3             |                       |          1 |
   | employees1 | p4             |                       |          1 |
   +------------+----------------+-----------------------+------------+
   5 rows in set (0.01 sec)
   ```

+ 这次每个分区有一行数据。

### 步骤 3. 创建新的 Key 分区表 `employees2`

   ```sql
   CREATE TABLE employees2(
      id INT NOT NULL,
      fname VARCHAR(30),
      lname VARCHAR(30),
      hired DATE NOT NULL DEFAULT '1970-01-01',
      job_code INT
   )
   PARTITION BY KEY(hired)
   PARTITIONS 5;
   ```

   ```output
   Query OK, 0 rows affected (0.54 sec)
   ```

### 步骤 4. 向 `employees2` 插入一些数据

   ```sql
   INSERT INTO employees2 VALUES(1, 'Jim', 'Lee', '2023-04-04', 2);
   INSERT INTO employees2 VALUES(2, 'Tim', 'Anderson', '2023-05-10', 2);
   INSERT INTO employees2 VALUES(3, 'Mike', 'Jackson', '2023-05-10', 3);
   INSERT INTO employees2 VALUES(4, 'Benjamin', 'Thompson', '2023-09-24', 1);
   INSERT INTO employees2 VALUES(5, 'Charlotte', 'Clark', '2023-09-24', 1);
   ```

   ```output
   Query OK, 1 row affected (0.00 sec)
   ```

+ 插入到 `employees2` 中的所有行的 `hired` 值都不同，但`YEAR(hired)` 的 `VALUES` 相同。让我们检查一下数据的分布情况。

   ```sql
   ANALYZE TABLE employees2;
   SELECT table_name, partition_name, partition_description, table_rows FROM information_schema.partitions WHERE table_schema = 'test' AND table_name='employees2'
   ORDER BY partition_name;
   ```

   ```output
   +------------+----------------+-----------------------+------------+
   | table_name | partition_name | partition_description | table_rows |
   +------------+----------------+-----------------------+------------+
   | employees2 | p0             |                       |          2 |
   | employees2 | p1             |                       |          2 |
   | employees2 | p2             |                       |          0 |
   | employees2 | p3             |                       |          1 |
   | employees2 | p4             |                       |          0 |
   +------------+----------------+-----------------------+------------+
   5 rows in set (0.02 sec)
   ```

+ 这些行分布在 3 个分区中，YEAR(hired) 的值相同。让我们截断表 `employees2` 并再次插入 5 行新数据。

   ```sql
   TRUNCATE TABLE employees2;
   INSERT INTO employees2 VALUES(1, 'Jim', 'Lee', '2021-05-10', 2);
   INSERT INTO employees2 VALUES(2, 'Tim', 'Anderson', '2021-05-10', 2);
   INSERT INTO employees2 VALUES(3, 'Mike', 'Jackson', '2021-05-10', 3);
   INSERT INTO employees2 VALUES(4, 'Benjamin', 'Thompson', '2021-05-10', 1);
   INSERT INTO employees2 VALUES(5, 'Charlotte', 'Clark', '2021-05-10', 1);
   ```

   ```output
   Query OK, 1 row affected (0.00 sec)
   ```

+ 插入到 `employees2` 中的所有行的 `hired` 值都相同。让我们检查一下数据的分布情况。

   ```sql
   ANALYZE TABLE employees2;
   SELECT table_name, partition_name, partition_description, table_rows FROM information_schema.partitions WHERE table_schema = 'test' AND table_name='employees2'
   ORDER BY partition_name;
   ```

   ```output
   +------------+----------------+-----------------------+------------+
   | table_name | partition_name | partition_description | table_rows |
   +------------+----------------+-----------------------+------------+
   | employees2 | p0             |                       |          0 |
   | employees2 | p1             |                       |          0 |
   | employees2 | p2             |                       |          0 |
   | employees2 | p3             |                       |          0 |
   | employees2 | p4             |                       |          5 |
   +------------+----------------+-----------------------+------------+
   5 rows in set (0.01 sec)
   ```

+ 所有行都存储在分区 `p4`。为什么呢？让我们截断表 `employees2` 并再次插入 5 行新数据。

   ```sql
   TRUNCATE TABLE employees2;
   INSERT INTO employees2 VALUES(1, 'Jim', 'Lee', '2020-04-04', 2);
   INSERT INTO employees2 VALUES(2, 'Tim', 'Anderson', '2021-05-10', 2);
   INSERT INTO employees2 VALUES(3, 'Mike', 'Jackson', '2022-05-10', 3);
   INSERT INTO employees2 VALUES(4, 'Benjamin', 'Thompson', '2023-09-24', 1);
   INSERT INTO employees2 VALUES(5, 'Charlotte', 'Clark', '2024-09-24', 1);
   ```

   ```output
   Query OK, 1 row affected (0.00 sec)
   ```

+ 插入到 `employees2` 中的所有行的 `hired` 值都不同。让我们检查一下数据的分布情况。

   ```sql
   ANALYZE TABLE employees2;
   SELECT table_name, partition_name, partition_description, table_rows FROM information_schema.partitions WHERE table_schema = 'test' AND table_name='employees2' ORDER BY partition_name;
   ```

   ```output
   +------------+----------------+-----------------------+------------+
   | table_name | partition_name | partition_description | table_rows |
   +------------+----------------+-----------------------+------------+
   | employees2 | p0             |                       |          1 |
   | employees2 | p1             |                       |          2 |
   | employees2 | p2             |                       |          1 |
   | employees2 | p3             |                       |          0 |
   | employees2 | p4             |                       |          1 |
   +------------+----------------+-----------------------+------------+
   5 rows in set (0.01 sec)
   ```

### 步骤 5. 清理表

   ```sql
   DROP TABLE employees1;
   DROP TABLE employees2;
   ```

   ```output
   Query OK, 0 rows affected (0.53 sec)
   ```
