List:Internals« Previous MessageNext Message »
From:jstephens Date:November 4 2005 11:53am
Subject:svn commit - mysqldoc@docsrva: r244 - in trunk: refman-5.1 refman-common
View as plain text  
Author: jstephens
Date: 2005-11-04 12:53:10 +0100 (Fri, 04 Nov 2005)
New Revision: 244

Log:

refman-5.1/partitioning.xml 
  - New section, discusses how partitioning handles NULL in partitioning 
    expressions, with examples; response to Bug#13443 (intended behaviour, but 
    needed to be explained in docs)

refman-common/titles.en.ent - Added new section title



Modified:
   trunk/refman-5.1/partitioning.xml
   trunk/refman-common/titles.en.ent

Modified: trunk/refman-5.1/partitioning.xml
===================================================================
--- trunk/refman-5.1/partitioning.xml	2005-11-04 09:59:17 UTC (rev 243)
+++ trunk/refman-5.1/partitioning.xml	2005-11-04 11:53:10 UTC (rev 244)
@@ -482,10 +482,10 @@
 </programlisting>
 
     <para>
-      This is because MySQL see no difference between the partition
+      This is because MySQL sees no difference between the partition
       names <literal>mypart</literal> and <literal>MyPart</literal>.
     </para>
-
+    
     <para>
       <emphasis role="bold">Note</emphasis>: In the sections that
       follow, we do not necessarily provide all possible forms for the
@@ -1760,7 +1760,209 @@
       </itemizedlist>
 
     </section>
+    
+    <section id="partitioning-handling-nulls">
+      <title id="title-partitioning-handling-nulls">&title-partitioning-handling-nulls;</title>
+      
+      <para>
+        Partitioning in MySQL does nothing to disallow
+        <literal>NULL</literal> as the value of a partitioning
+        expression, whether it is a column value or the value of a
+        user-supplied expression. In general, MySQL will treat a
+        <literal>NULL</literal> as a zero in such cases. If you wish to
+        circumvent this behaviour, you should design tables so as not to
+        allow nulls; most likely you can do so by declaring columns
+        <literal>NOT NULL</literal>.  
+      </para>
+      
+      <para>
+        In this section, we provide some examples illustrating how MySQL
+        handles <literal>NULL</literal> values when determining the
+        partition in which a row should be stored. 
+      </para>
+      
+      <para>
+        If you insert a row into a table partitioned by
+        <literal>RANGE</literal> or <literal>LIST</literal> such that
+        the column value used to determine the partition is
+        <literal>NULL</literal>, it is treated as <literal>0</literal>.
+        For example, consider these two tables, created and populated as
+        follows:
+      </para>
+    
+<programlisting>
+mysql&gt; <userinput>CREATE TABLE tnlist (</userinput>
+    -&gt;     <userinput>id INT,</userinput>
+    -&gt;     <userinput>name VARCHAR(5)</userinput>
+    -&gt; <userinput>)</userinput>
+    -&gt; <userinput>PARTITION BY LIST(id) (</userinput>
+    -&gt;     <userinput>PARTITION p1 VALUES IN (0),</userinput>
+    -&gt;     <userinput>PARTITION p2 VALUES IN (1)</userinput>
+    -&gt; <userinput>);</userinput>
+Query OK, 0 rows affected (0.09 sec)
 
+mysql&gt; <userinput>CREATE TABLE tnrange (</userinput>
+    -&gt;     <userinput>id INT,</userinput>
+    -&gt;     <userinput>name VARCHAR(5)</userinput>
+    -&gt; <userinput>)</userinput>
+    -&gt; <userinput>PARTITION BY RANGE(id) (</userinput>
+    -&gt;     <userinput>PARTITION p1 VALUES LESS THAN (1),</userinput>
+    -&gt;     <userinput>PARTITION p2 VALUES LESS THAN MAXVALUE</userinput>
+    -&gt; <userinput>);</userinput>
+Query OK, 0 rows affected (0.09 sec)
+
+mysql&gt; <userinput>INSERT INTO tnlist VALUES (NULL, 'bob');</userinput>
+Query OK, 1 row affected (0.00 sec)
+
+mysql&gt; <userinput>INSERT INTO tnrange VALUES (NULL, 'jim');</userinput>
+Query OK, 1 row affected (0.00 sec)
+
+mysql&gt; <userinput>SELECT * FROM tnlist;</userinput>
++------+------+
+| id   | name |
++------+------+
+| NULL | bob  |
++------+------+
+1 row in set (0.00 sec)
+
+mysql&gt; <userinput>SELECT * FROM tnrange;</userinput>
++------+------+
+| id   | name |
++------+------+
+| NULL | jim  |
++------+------+
+1 row in set (0.00 sec)
+</programlisting>
+      
+      <para>
+        In both tables, the <literal>id</literal> column was not
+        declared as <literal>NOT NULL</literal>, which means that it
+        admits <literal>NULL</literal> values. You can verify that the
+        rows were stored in the partitions <literal>p1</literal> of the
+        each table by dropping these partitions, and then re-running the
+        <literal>SELECT</literal> statements:
+      </para>
+
+<programlisting>
+mysql&gt; <userinput>ALTER TABLE tnlist DROP PARTITION p1;</userinput>
+Query OK, 0 rows affected (0.16 sec)
+
+mysql&gt; <userinput>ALTER TABLE tnrange DROP PARTITION p1;</userinput>
+Query OK, 0 rows affected (0.16 sec)
+
+mysql&gt; <userinput>SELECT * FROM tnlist;</userinput>
+Empty set (0.00 sec)
+
+mysql&gt; <userinput>SELECT * FROM tnrange;</userinput>
+Empty set (0.00 sec)
+</programlisting>
+      
+      <para>
+        In the case of partitioning by <literal>HASH</literal> or
+        <literal>KEY</literal>, any partition expression that yields a
+        <literal>NULL</literal> value is treated as though its return
+        value were zero. We can verify this behaviour by examining the
+        effects on the filesystem of creating a table partitioned by
+        <literal>HASH</literal> and populating it with a record
+        containing appropriate values. Suppose you have a table
+        <literal>tnhash</literal>, created in the
+        <literal>test</literal> database, using this statement: 
+    </para>
+
+<programlisting>
+CREATE TABLE tnhash (
+    id INT,
+    name VARCHAR(5)
+)
+PARTITION BY HASH(id)
+PARTITIONS 2;
+</programlisting>
+      
+      <para>
+        Assuming an RPM installation of MySQL on Linux, this statement
+        creates two <filename>.MYD</filename> files in
+        <filename>/var/lib/mysql/test</filename>, which can be viewed in
+        the <command>bash</command> shell as follows:
+      </para>
+
+<programlisting>
+/var/lib/mysql/test> <userinput>ls *.MYD -l</userinput>
+-rw-rw----  1 mysql mysql 0 2005-11-04 18:41 tnhash_p0.MYD
+-rw-rw----  1 mysql mysql 0 2005-11-04 18:41 tnhash_p1.MYD
+</programlisting>
+    
+      <para>
+        Note that the size of each file is 0 bytes. Now insert a row
+        into <literal>tnhash</literal> whose <literal>id</literal>
+        column value is <literal>NULL</literal> and verify that this row
+        was inserted:
+      </para>
+
+<programlisting>
+mysql&gt; <userinput>INSERT INTO tnhash VALUES (NULL, 'sam');</userinput>
+Query OK, 1 row affected (0.00 sec)
+
+mysql&gt; <userinput>SELECT * FROM tnhash;</userinput>
++------+------+
+| id   | name |
++------+------+
+| NULL | sam  |
++------+------+
+1 row in set (0.01 sec)
+</programlisting>
+        
+      <para>
+        Recall that for any integer <replaceable>N</replaceable>, the
+        value of <literal>NULL MOD
+          <replaceable>N</replaceable></literal> is always
+        <literal>NULL</literal>. This result is treated for determining
+        the correct partition as <literal>0</literal>. Returning to the
+        system shell (still assuming <command>bash</command> for this
+        purpose), we can see that the value was inserted into the first
+        partition (named <literal>p0</literal> by default) by listing
+        the data files once again:
+      </para>
+    
+<programlisting>
+var/lib/mysql/test> <userinput>ls *.MYD -l</userinput>
+-rw-rw----  1 mysql mysql 20 2005-11-04 18:44 tnhash_p0.MYD
+-rw-rw----  1 mysql mysql  0 2005-11-04 18:41 tnhash_p1.MYD
+</programlisting>
+      
+      <para>
+        You can see that the <literal>INSERT</literal> statement
+        modified only the file <filename>tnhash_p0.MYD</filename>,
+        increasing its size on disk, without affecting the other data
+        file.
+      </para>
+      
+      <para>
+        Suppose we have a table such as this one:
+      </para>
+
+<programlisting>
+CREATE TABLE tndate (
+    id INT,
+    dt DATE
+)
+PARTITION BY RANGE( YEAR(dt) ) (
+    PARTITION p0 VALUES LESS THAN (1990),
+    PARTITION p1 VALUES LESS THAN (2000),
+    PARTITION p2 VALUES LESS THAN MAXVALUE
+);
+</programlisting>
+      
+      <para>
+        As with other MySQL functions, <literal>YEAR(NULL)</literal>
+        returns <literal>NULL</literal>. A row with a
+        <literal>dt</literal> column value of <literal>NULL</literal> is
+        treated as though the partitioning expression evaluated to
+        <literal>0</literal>, and is inserted into partition
+        <literal>p0</literal>.
+      </para>
+      
+    </section>    
+    
   </section>
 
   <section id="partitioning-management">
@@ -2132,7 +2334,7 @@
         partitioned by range, you can use <literal>ADD
         PARTITION</literal> to add new partitions to the high end of the
         partitions list only. Trying to add a new partition in this
-        manner between or before existing partitions will result n an
+        manner between or before existing partitions will result in an
         error as shown here:
       </para>
 

Modified: trunk/refman-common/titles.en.ent
===================================================================
--- trunk/refman-common/titles.en.ent	2005-11-04 09:59:17 UTC (rev 243)
+++ trunk/refman-common/titles.en.ent	2005-11-04 11:53:10 UTC (rev 244)
@@ -1242,6 +1242,7 @@
 <!ENTITY title-partitioning-range "<literal>RANGE</literal> Partitioning">
 <!ENTITY title-partitioning-list "<literal>LIST</literal> Partitioning">
 <!ENTITY title-partitioning-subpartitions "Subpartitioning">
+<!ENTITY title-partitioning-handling-nulls "How MySQL Partitioning Handles <literal>NULL</literal> Values">
 <!ENTITY title-partitioning-management "Partition Management">
 <!ENTITY title-partitioning-management-range-list "Management of <literal>RANGE</literal> and <literal>LIST</literal> Partitions">
 <!ENTITY title-partitioning-management-hash-key "Management of <literal>HASH</literal> and <literal>KEY</literal> Partitions">

Thread
svn commit - mysqldoc@docsrva: r244 - in trunk: refman-5.1 refman-commonjstephens4 Nov