Rechercher dans le manuel MySQL
23.2.7 How MySQL Partitioning Handles NULL
Partitioning in MySQL does nothing to disallow
NULL
as the value of a partitioning
expression, whether it is a column value or the value of a
user-supplied expression. Even though it is permitted to use
NULL
as the value of an expression that must
otherwise yield an integer, it is important to keep in mind that
NULL
is not a number. MySQL's
partitioning implementation treats NULL
as
being less than any non-NULL
value, just as
ORDER BY
does.
This means that treatment of NULL
varies
between partitioning of different types, and may produce
behavior which you do not expect if you are not prepared for it.
This being the case, we discuss in this section how each MySQL
partitioning type handles NULL
values when
determining the partition in which a row should be stored, and
provide examples for each.
Handling of NULL with RANGE partitioning.
If you insert a row into a table partitioned by
RANGE
such that the column value used to
determine the partition is NULL
, the row is
inserted into the lowest partition. Consider these two tables
in a database named p
, created as follows:
- -> )
- -> );
- Query OK, 0 rows affected (0.09 sec)
- -> )
- -> );
- Query OK, 0 rows affected (0.09 sec)
You can see the partitions created by these two
CREATE TABLE
statements using the
following query against the
PARTITIONS
table in the
INFORMATION_SCHEMA
database:
- > FROM INFORMATION_SCHEMA.PARTITIONS
- +------------+----------------+------------+----------------+-------------+
- +------------+----------------+------------+----------------+-------------+
- | t1 | p0 | 0 | 0 | 0 |
- | t1 | p1 | 0 | 0 | 0 |
- | t1 | p2 | 0 | 0 | 0 |
- | t2 | p0 | 0 | 0 | 0 |
- | t2 | p1 | 0 | 0 | 0 |
- | t2 | p2 | 0 | 0 | 0 |
- | t2 | p3 | 0 | 0 | 0 |
- +------------+----------------+------------+----------------+-------------+
(For more information about this table, see
Section 25.17, “The INFORMATION_SCHEMA PARTITIONS Table”.) Now let us populate each of
these tables with a single row containing a
NULL
in the column used as the partitioning
key, and verify that the rows were inserted using a pair of
SELECT
statements:
- Query OK, 1 row affected (0.00 sec)
- Query OK, 1 row affected (0.00 sec)
- +------+--------+
- | id | name |
- +------+--------+
- +------+--------+
- +------+--------+
- | id | name |
- +------+--------+
- +------+--------+
You can see which partitions are used to store the inserted rows
by rerunning the previous query against
INFORMATION_SCHEMA.PARTITIONS
and
inspecting the output:
- > FROM INFORMATION_SCHEMA.PARTITIONS
- +------------+----------------+------------+----------------+-------------+
- +------------+----------------+------------+----------------+-------------+
- | t1 | p0 | 1 | 20 | 20 |
- | t1 | p1 | 0 | 0 | 0 |
- | t1 | p2 | 0 | 0 | 0 |
- | t2 | p0 | 1 | 20 | 20 |
- | t2 | p1 | 0 | 0 | 0 |
- | t2 | p2 | 0 | 0 | 0 |
- | t2 | p3 | 0 | 0 | 0 |
- +------------+----------------+------------+----------------+-------------+
You can also demonstrate that these rows were stored in the
lowest-numbered partition of each table by dropping these
partitions, and then re-running the
SELECT
statements:
- Query OK, 0 rows affected (0.16 sec)
- Query OK, 0 rows affected (0.16 sec)
(For more information on ALTER TABLE ... DROP
PARTITION
, see Section 13.1.9, “ALTER TABLE Syntax”.)
NULL
is also treated in this way for
partitioning expressions that use SQL functions. Suppose that we
define a table using a CREATE
TABLE
statement such as this one:
As with other MySQL functions,
YEAR(NULL)
returns
NULL
. A row with a dt
column value of NULL
is treated as though the
partitioning expression evaluated to a value less than any other
value, and so is inserted into partition p0
.
Handling of NULL with LIST partitioning.
A table that is partitioned by LIST
admits
NULL
values if and only if one of its
partitions is defined using that value-list that contains
NULL
. The converse of this is that a table
partitioned by LIST
which does not
explicitly use NULL
in a value list rejects
rows resulting in a NULL
value for the
partitioning expression, as shown in this example:
- -> )
- -> );
- Query OK, 0 rows affected (0.01 sec)
Only rows having a c1
value between
0
and 8
inclusive can be
inserted into ts1
. NULL
falls outside this range, just like the number
9
. We can create tables
ts2
and ts3
having value
lists containing NULL
, as shown here:
- -> )
- -> );
- Query OK, 0 rows affected (0.01 sec)
- -> )
- -> );
- Query OK, 0 rows affected (0.01 sec)
When defining value lists for partitioning, you can (and should)
treat NULL
just as you would any other value.
For example, both VALUES IN (NULL)
and
VALUES IN (1, 4, 7, NULL)
are valid, as are
VALUES IN (1, NULL, 4, 7)
, VALUES IN
(NULL, 1, 4, 7)
, and so on. You can insert a row
having NULL
for column c1
into each of the tables ts2
and
ts3
:
- Query OK, 1 row affected (0.00 sec)
- Query OK, 1 row affected (0.00 sec)
By issuing the appropriate query against
INFORMATION_SCHEMA.PARTITIONS
, you
can determine which partitions were used to store the rows just
inserted (we assume, as in the previous examples, that the
partitioned tables were created in the p
database):
- > FROM INFORMATION_SCHEMA.PARTITIONS
- +------------+----------------+------------+----------------+-------------+
- +------------+----------------+------------+----------------+-------------+
- | ts2 | p0 | 0 | 0 | 0 |
- | ts2 | p1 | 0 | 0 | 0 |
- | ts2 | p2 | 0 | 0 | 0 |
- | ts2 | p3 | 1 | 20 | 20 |
- | ts3 | p0 | 0 | 0 | 0 |
- | ts3 | p1 | 1 | 20 | 20 |
- | ts3 | p2 | 0 | 0 | 0 |
- +------------+----------------+------------+----------------+-------------+
As shown earlier in this section, you can also verify which
partitions were used for storing the rows by deleting these
partitions and then performing a
SELECT
.
Handling of NULL with HASH and KEY partitioning.
NULL
is handled somewhat differently for
tables partitioned by HASH
or
KEY
. In these cases, any partition
expression that yields a NULL
value is
treated as though its return value were zero. We can verify
this behavior by examining the effects on the file system of
creating a table partitioned by HASH
and
populating it with a record containing appropriate values.
Suppose that you have a table th
(also in
the p
database) created using the following
statement:
- -> )
- -> PARTITIONS 2;
- Query OK, 0 rows affected (0.00 sec)
The partitions belonging to this table can be viewed using the query shown here:
- > FROM INFORMATION_SCHEMA.PARTITIONS
- +------------+----------------+------------+----------------+-------------+
- +------------+----------------+------------+----------------+-------------+
- | th | p0 | 0 | 0 | 0 |
- | th | p1 | 0 | 0 | 0 |
- +------------+----------------+------------+----------------+-------------+
TABLE_ROWS
for each partition is 0. Now
insert two rows into th
whose
c1
column values are NULL
and 0, and verify that these rows were inserted, as shown here:
- Query OK, 1 row affected (0.00 sec)
- +------+---------+
- | c1 | c2 |
- +------+---------+
- +------+---------+
- | 0 | gigan |
- +------+---------+
Recall that for any integer N
, the
value of NULL MOD
is always
N
NULL
. For tables that are partitioned by
HASH
or KEY
, this result
is treated for determining the correct partition as
0
. Checking the
INFORMATION_SCHEMA.PARTITIONS
table
once again, we can see that both rows were inserted into
partition p0
:
- > FROM INFORMATION_SCHEMA.PARTITIONS
- +------------+----------------+------------+----------------+-------------+
- +------------+----------------+------------+----------------+-------------+
- | th | p0 | 2 | 20 | 20 |
- | th | p1 | 0 | 0 | 0 |
- +------------+----------------+------------+----------------+-------------+
By repeating the last example using PARTITION BY
KEY
in place of PARTITION BY HASH
in the definition of the table, you can verify that
NULL
is also treated like 0 for this type of
partitioning.
Traduction non disponible
Le manuel MySQL n'est pas encore traduit en français sur l'infobrol. Seule la version anglaise est disponible pour l'instant.
Document créé le 26/06/2006, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/mysql-rf-partitioning-handling-nulls.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.