programmera.net -> mysql -> normal     för utskrift      info@programmera.net

Datatyper i MySQL

1. Numeriska Datatyper
2. Numeriska typer och DEFAULT
3. Numeriska typer och NULL
4. Numeriska typer och felaktiga invärden
5. Heltal
6. FLOAT och DOUBLE
7. DECIMAL

1. Numeriska Datatyper

Det numeriska datatyper som finns i MySQL är:

Datatyp Bytes Motsvarar i Java. Beskrivning
TINYINT  1  (byte)  Ett heltal som spänner mellan -128 till 127 eller 0 till 255.
SMALLINT  2  (short)  Ett heltal som spänner mellan -2^15 till 2^15-1 eller 0 till 2^16.
MEDIUMINT  3  (-)  Ett heltal som spänner mellan -2^23 till 2^23-1 eller 0 till 2^24.
INT  4  (int)  Ett heltal som spänner mellan -2^31 till 2^31-1 eller 0 till 2^32.
BIGINT  8  (long)  Ett heltal som spänner mellan -2^63 till 2^63-1 eller 0 till 2^64.
FLOAT  4  (float)  Ett flyttal som lagras i ett format beroende på CPU.
DOUBLE  8  (double)  Ett flyttal som lagras i ett format beroende på CPU.
DECIMAL  L  (-)  Ett flyttal som lagras som en sträng med längden L.

2. Numeriska typer och DEFAULT

Om man inte skriver ett explicit värde för en kolumn i en INSERT-sats lagras ett defaultvärde. De olika numeriska datatyperna följer följande regler när det gäller defaultvärden:

  1. En kolumn som har ett explicit defaultvärde lagrar defaultvärdet.
  2. En kolumn som ej har ett explicit defaultvärde och som kan innehålla NULL, lagrar NULL.
  3. En kolumn som ej har ett explicit defaultvärde och som ej kan innehålla NULL, lagrar 0.
Vi testar defaultvärden för olika fall:
mysql> CREATE TABLE number_table(
    -> int_col1 INT,
    -> int_col2 INT DEFAULT 17,
    -> int_col3 INT NOT NULL,
    -> float_col1 FLOAT,
    -> float_col2 FLOAT DEFAULT 17.17,
    -> float_col3 FLOAT NOT NULL,
    -> dec_col1 DECIMAL,
    -> dec_col2 DECIMAL DEFAULT 17.17,
    -> dec_col3 DECIMAL NOT NULL
    -> );
Query OK, 0 rows affected (0.05 sec)
    
INSERT INTO number_table VALUES ();
Query OK, 1 row affected (0.02 sec)

SELECT * FROM number_table\G
*************************** 1. row ***************************
  int_col1: NULL
  int_col2: 17
  int_col3: 0
float_col1: NULL
float_col2: 17.17
float_col3: 0
  dec_col1: NULL
  dec_col2: 17
  dec_col3: 0
1 row in set (0.00 sec)

3. Numeriska typer och NULL

Om man explicit försöker lagra NULL i en textkolumn har vi följande fall:

  1. Om en kolumn kan innehålla NULL sätts den till NULL.
  2. Om en NOT NULL-kolumn sätts till NULL i en UPDATE får kolumnen värdet 0, och en varning läggs till på slutet.
  3. Om en NOT NULL-kolumn sätts till NULL i en INSERT genereras ett fel och satsen abryts.
Vi testar att göra INSERT med NULL:
mysql> INSERT INTO number_table (int_col1, int_col2, int_col3) VALUES(NULL, NULL, NULL);
ERROR 1048: Column 'int_col3' cannot be null
Här ser vi att det är först vid "int_col3" då MySQL protesterar. Nu ska vi se om det går att göra UPDATE med NULL på den kolumnen:
mysql> UPDATE number_table SET int_col3=NULL;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 1

SELECT int_col3 FROM number_table;
+----------+
| int_col3 |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
Här kommer vi undan med en varning.

4. Numeriska typer och felaktiga invärden

Det finns två sätt som man kan ge felaktiga invärden till en numerisk datatyp:

  • Man kan ge ett värde som ligger utanför typens max/min-värde. Om detta sker lagras max eller minvärdet för typen. Om man t.ex. försöker lagra 1000 i en TINYINT så lagras 127 (som är det största värdet möjligt för en TINYINT).
  • Man försöker lagra en sträng som inte innehåller numeriska tecken. Om detta sker lagrar MySQL alla tecken fram till det ickenumeriska tecknet.
Vi tittar på ett exempel:
mysql> CREATE TABLE range_table(
    -> tiny_col TINYINT,
    -> int_col INT,
    -> dec_col DECIMAL,
    -> float_col FLOAT
    -> );
Query OK, 0 rows affected (0.03 sec)

INSERT INTO range_table VALUES ('-1000', '-12a12', '-12a12', '-12a12');
Query OK, 1 row affected (0.00 sec)

SELECT * FROM range_table;
+----------+---------+---------+-----------+
| tiny_col | int_col | dec_col | float_col |
+----------+---------+---------+-----------+
|     -128 |     -12 |     -12 |       -12 |
+----------+---------+---------+-----------+
1 row in set (0.00 sec)

5. Heltal

Heltalstyperna är TINYINT, SMALLINT, MEDIUMINT, INT och BIGINT. Dessa typer använder olika många bytes för lagring, minst är TINYINT som använder 1 byte och störst är BIGINT som använder 8 bytes per tal. Per default kan ett heltal innehålla negativa värden, men genom att lägga till nyckelordet UNSIGNED tolkas alla bitarna som ett positivt heltal. Följande exempel visar en tabell innehållande ett positivt heltal "age":
mysql> CREATE TABLE person (
    -> age INT UNSIGNED NOT NULL
    -> );
Du kan ange talets vidd genom att ange ett värde inom parantes efter talet. Vidden bestämmer hur många värdesiffror som ska visas då talet visas:
mysql> CREATE TABLE person (
    -> age INT(4) UNSIGNED NOT NULL
    -> );
Som default sätts vidden till max. T.ex. för typen SHORT som har som längsta tal "-32768" är defaultvidden 6 (för att alla siffror och minustecknet ska få plats). Var inte orolig för att någon värdesiffra inte visas. Om något tal har fler värdesiffror än den vidd du givit kommer vidden automatiskt att ökas.

6. FLOAT och DOUBLE

Flyttalstyperna är FLOAT, DOUBLE. De lagrar ett flyttal i samma format som datorns CPU använder. Detta är ett effektivt format för lagring och beräkningar, men avrundningsfel förekommer. Man kan bestämma vidden genom att ge två tal inom parantes vid kolumndeklarationen. Det första talet bestämmer hur många värdesiffror som ska visas, det andra hur många värdesiffror som ska stå till höger om decimaltecknet. Ett exempel:
mysql> CREATE TABLE float_table (
    -> weight FLOAT(6,2)
    -> );

INSERT INTO float_table VALUES (123.4),(1.2345);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

SELECT * FROM float_table;
+--------+
| weight |
+--------+
| 123.40 |
|   1.23 |
+--------+
2 rows in set (0.00 sec)
Här visas totalt 6 värdesiffror i kolumnen "weight", med 4 värdesiffror före decimaltecknet och 2 efter. Värdesiffror till vänster om decimalen trunkeras inte, som synes i följande exempel:
mysql> INSERT INTO float_table VALUES (1234567);
Query OK, 1 row affected (0.00 sec)

SELECT * FROM float_table;
+------------+
| weight     |
+------------+
|     123.40 |
|       1.23 |
| 1234567.00 |
+------------+
3 rows in set (0.00 sec)
De värdesiffror som inte syns är trunkerde. För att visa detta ändrar vi på längden på tabellen "float_table":
mysql> ALTER TABLE float_table MODIFY weight FLOAT(10,5);
Query OK, 3 rows affected (0.11 sec)
Records: 3  Duplicates: 0  Warnings: 0

SELECT * FROM float_table;
+---------------+
| weight        |
+---------------+
|     123.40000 |
|       1.23000 |
| 1234567.00000 |
+---------------+
3 rows in set (0.00 sec)
Här skulle hela talet "1.2345" ha visats, om det inte var trunkerat.

7. DECIMAL

Denna datatyp lagras som en sträng i MySQL med en byte per siffra. Genom detta lagringssätt får man inget avrundningsfel på sista decimalen, detta kan vara bra om man räknar med valutor. Nackdelen är att lagringssättet är ineffektivt. Ett exempel:
mysql> CREATE TABLE dec_table (
    -> income DECIMAL(10,2)
    -> );
Längden är per default 10 med inga decimaler OBS! Skillnaden mellan DECIMAL och andra numeriska datatyper är att den vidd du bestämmer avgör hur många bytes som ska användas för lagringen av talet.
mysql> INSERT INTO dec_table VALUES(1.1234), (777.77);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

SELECT * FROM dec_table;
+--------+
| income |
+--------+
|   1.12 |
| 777.77 |
+--------+
2 rows in set (0.00 sec)