Przypuśćmy, że mamy następującą tak zdefiniowaną tabelę, z kolumnami typu enum:
mysql> show create table test_enum \G
*************************** 1. row ***************************
Table: test_enum
Create Table: CREATE TABLE `test_enum` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`e1` enum('Y','F','') DEFAULT NULL,
`e2` enum('Y','F') NOT NULL DEFAULT 'Y',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Wstawmy kilka wierszy:mysql> insert into test_enum (e1,e2) VALUES ('Y','Y'),('F','F'),('',''),(NULL,NULL),('N','N');
Query OK, 5 rows affected, 4 warnings (0.06 sec)
Records: 5 Duplicates: 0 Warnings: 4
mysql> show warnings;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1265 | Data truncated for column 'e2' at row 3 |
| Warning | 1048 | Column 'e2' cannot be null |
| Warning | 1265 | Data truncated for column 'e1' at row 5 |
| Warning | 1265 | Data truncated for column 'e2' at row 5 |
+---------+------+-----------------------------------------+
4 rows in set (0.00 sec)
mysql> select * from test_enum;
+----+------+----+
| id | e1 | e2 |
+----+------+----+
| 1 | Y | Y |
| 2 | F | F |
| 3 | | |
| 4 | NULL | |
| 5 | | |
+----+------+----+
5 rows in set (0.00 sec)
Zauważyliście coś ciekawego? Dwa pierwsze wpisy raczej nikogo nie dziwią - w końcu są poprawne. Jednak gdy przyjrzymy się trzem następnym, zauważymy że:- insert stringa pustego '' do kolumny e2 powoduje wstawienie tej właśnie wartości, mimo iż nie ma jej zdefiniowanej jako wartość dozwolona,
- insert NULLa do kolumny e2 powoduje wstawienie pustego stringa mimo iż mamy zdefiniowaną wartość domyślną,
- insert wartości niepoprawnych powodują ustawienie na puste stringi.
Zanim omówię powyższe 'niespodzianki' wstawmy jeszcze dwa rekordy:
mysql> insert into test_enum (e1) VALUES (NULL); Query OK, 1 row affected (0.02 sec) mysql> insert into test_enum (id) VALUES (7); Query OK, 1 row affected (0.05 sec) mysql> select * from test_enum where id > 5; +----+------+----+ | id | e1 | e2 | +----+------+----+ | 6 | NULL | Y | | 7 | NULL | Y | +----+------+----+ 2 rows in set (0.00 sec)Tym razem nasze dane są takie jakich byśmy się spodziewali.
Cechy typu ENUM, których być może się nie spodziewaliście:
- Typ ENUM jest obiektem, który definiuje wartości dozwolone w formie stringów, ale tak na prawdę wartość zapisywana jest przy pomocy indexów typu integer, zaczynając od 1. Weźmy pod uwagę kolumnę e1 naszej tabeli test_enum. Wartości ('Y','F','') są zapisywane jako (1,2,3). Poniżej przedstawię kilka przykładów SELECTów.
- Wartość 0 jest zarezerwowana dla pustego stringa - wartość błędu.
- Wartość NULL jest zapisywana jako NULL lub wartość błędu (jeśli kolumna jest zdefiniowana jako NOT NULL).
- Jeśli zdfiniujemy enum jako ciagi znaków numerycznych, to wartości wstawiane do takiej kolumny są traktowane jako indexy dopuszczalnych wartości (zobacz poniższy przykład 2, dla tablicy test_enum2).
Przykład 1: Przykłady wyszukiwania wierszy po wartościach lub indexach dopuszczalnych wartości:
mysql> SELECT * FROM test_enum WHERE e1 = ''; +----+------+----+ | id | e1 | e2 | +----+------+----+ | 3 | | | | 5 | | | +----+------+----+ 2 rows in set (0.00 sec) mysql> SELECT * FROM test_enum WHERE e1 = 0; +----+------+----+ | id | e1 | e2 | +----+------+----+ | 5 | | | +----+------+----+ 1 row in set (0.00 sec) mysql> SELECT * FROM test_enum WHERE e1 = 3; +----+------+----+ | id | e1 | e2 | +----+------+----+ | 3 | | | +----+------+----+ 1 row in set (0.00 sec)
Przykład 2: Inny przykład tablicy z columną typu enum:
mysql> show create table test_enum2 \G
*************************** 1. row ***************************
Table: test_enum2
Create Table: CREATE TABLE `test_enum2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`e1` enum('0','1','2','3') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> INSERT INTO test_enum2 (e1) VALUES (1),('1'),('4');
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test_enum2;
+----+------+
| id | e1 |
+----+------+
| 1 | 0 |
| 2 | 1 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec)
Przykład 3: Aby podejrzeć wartość string i jej index wystraczy:
mysql> select id, e1, e1+0 from test_enum2; +----+------+------+ | id | e1 | e1+0 | +----+------+------+ | 1 | 0 | 1 | | 2 | 1 | 2 | | 3 | 3 | 4 | +----+------+------+ 3 rows in set (0.00 sec)Każdy nowy element wartości dopuszczalnej powinien być dopisany bez zmiany kolejności. W ten sposób nowa wartość będzie miała nadaną kolejną wartość indexu. W przeciwnym przypadku tablica będzieme musiała być przepisana aby starym wartościom nadać nowe indexy. Dla bardzo dużych tabel może być to czasochłonna opercja, a i chyba nie potrzebna.
Brak komentarzy:
Prześlij komentarz