[MySQL] restricciones de campo sql

En MySQL, los datos que necesitamos almacenar requieren diferentes restricciones en escenarios específicos. Cuando los datos recién insertados violan el campo de restricción del campo, MySQL prohibirá directamente la inserción.

  • El tipo de datos también es una restricción, pero la restricción del tipo de datos es demasiado simple;
  • Por ejemplo, si lo que necesito almacenar es un número de serie, entonces no puede haber un número negativo, en este caso se debe usar unsigned para restringir el número entero;
  • Si lo que quiero almacenar es una fecha, y cada campo de esta fecha debe tenerla, entonces es necesario restringirla NOT NULLpara que no esté vacía;
  • Si lo que quiero almacenar es una identificación de usuario, este valor debe ser único en todo el sistema de usuario y puedo usarlo UNIQUEpara limitar la unicidad.

Este artículo presenta principalmente los siguientes tipos de restricciones, que siguen siendo operaciones de declaración de tipo ddl en MySQL.

null/not null
default
comment
zerofill
primary key
auto_increment
unique key

Por cierto, en MySQL, el valor de cada columna se puede llamar o 字段; generalmente no se llama 键值.

Y cada fila de la tabla se llama一条记录

1. Atributo vacío

1.1 Descripción

El atributo vacío contiene dos valores, NULL/NOT NULLcorrespondientes a vacío y no vacío respectivamente.

En la base de datos, si no especificamos el valor de una columna al insertar una fila, la base de datos establecerá el valor en NULL;

Preste atención aquí para distinguir entre cadenas NULL y vacías. ¡Las cadenas vacías no son NULL!

Pero cuando realmente utilizamos los datos, suponiendo que se trata de datos enteros, debemos sacarlos y realizar operaciones con ellos. En este momento, el resultado obtenido por NULL no es un número y no hay forma de realizar operaciones. Muchas veces, estableceremos las restricciones de un campo NOT NULLy agregaremos un valor predeterminado (como 0 o una cadena vacía)

MariaDB [hello]> select null;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.000 sec)

MariaDB [hello]> select not null;
+----------+
| not null |
+----------+
|     NULL |
+----------+
1 row in set (0.001 sec)

Se puede ver a continuación que los atributos vacíos no pueden participar en las operaciones y el resultado será NULL sin importar cómo se realice la operación.

En Python, NULL corresponde directamente a Ninguno. Cuando intenta realizar operaciones con tipos Ninguno e int, Python informará un error. Lo mismo ocurre en el CPP.

MariaDB [hello]> select 1+null;
+--------+
| 1+null |
+--------+
|   NULL |
+--------+
1 row in set (0.001 sec)

1.2 Caso

Supongamos que tenemos una tabla correspondiente a clases y aulas de un piso, la cual contiene dos campos: número de clase y número de aula.

  • Si el número de clase está vacío, entonces no sabes qué clase hay en este salón de clases.
  • Si el número del aula está vacío, entonces no sabes dónde se lleva a cabo una determinada clase.

Se puede ver en el escenario real que ninguno de estos dos campos puede estar vacío, por lo que esto debe tenerse en cuenta al crear la tabla.

create table if not exists myclass(
	class_name varchar(30) not null,
    class_room varchar(30) not null
)default charset=utf8;

Después de crear la tabla, cuando intentamos insertar un campo NULL, aparecerá el siguiente mensaje, indicando que una determinada columna no puede estar vacía.

MariaDB [hello]> insert into myclass values ('510',NULL);
ERROR 1048 (23000): Column 'class_room' cannot be null

La cadena vacía se puede insertar. Esto ilustra una vez más que lo que pensamos no es lo mismo que NULL. La cadena vacía no es NULL.

MariaDB [hello]> insert into myclass values ('510','');
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from myclass;
+------------+------------+
| class_name | class_room |
+------------+------------+
| 510        |            |
+------------+------------+
1 row in set (0.000 sec)

2.Valor predeterminado predeterminado

Cuando nos registramos en ciertos sitios web, si alguna información no se completa, el sistema la establecerá como predeterminada.

Por ejemplo, cuando no selecciona su edad, el sistema puede mostrarle como 0 años; otros usuarios sabrán que no ingresó su edad real cuando vean los 0 años mostrados en su página de inicio personal. (Al desarrollar el front-end, también puede considerar 0 como no completado y mostrarlo como "edad oculta")

Otro ejemplo es que en nuestra web existe un valor para los puntos de usuario, cuando un usuario se registra los puntos deben ser 0 (por el momento no se considera la operación de dar puntos a nuevos usuarios), en este momento el valor por defecto de la columna de puntos se puede establecer en 0. No es necesario insertar explícitamente los datos en esta columna al insertar;

En MySQL, después de establecer un valor predeterminado para una columna. Si los datos de esta columna no se especifican al insertar, se utilizará el valor predeterminado.

create table if not exists web_user(
    name varchar(30) not null default '默认用户名',
    age tinyint not null default 0,
    gender char(2) not null default '男' 
);

Después de crear esta tabla, cuando miramos la estructura de la tabla, podemos ver si está vacía y los atributos relacionados predeterminados.

MariaDB [hello]> desc web_user;
+--------+-------------+------+-----+-----------------+-------+
| Field  | Type        | Null | Key | Default         | Extra |
+--------+-------------+------+-----+-----------------+-------+
| name   | varchar(30) | NO   |     | 默认用户名      |       |
| age    | tinyint(4)  | NO   |     | 0               |       |
| gender | char(2)     | NO   |     | 男              |       |
+--------+-------------+------+-----+-----------------+-------+
3 rows in set (0.004 sec)

Dado que hemos establecido valores iniciales para los tres campos de esta tabla, incluso puede insertar datos directamente sin especificar nada; como puede ver a continuación, todas las columnas están configuradas con los valores iniciales de la columna.

MariaDB [hello]> insert into web_user values ();
Query OK, 1 row affected (0.001 sec)

MariaDB [hello]> select * from web_user;
+-----------------+-----+--------+
| name            | age | gender |
+-----------------+-----+--------+
| 默认用户名      |   0 | 男     |
+-----------------+-----+--------+
1 row in set (0.000 sec)

Los valores predeterminados pueden ayudar cuando no queremos establecer el valor de una determinada columna.

Aquí hay una demostración de error. Solo configuramos dos valores en los valores. El propósito es permitir que el género del usuario recién insertado adopte el valor predeterminado. Pero MySQL informó un error: el mensaje de error era que el número de valores no era coherente con el número de columnas.

MariaDB [hello]> insert into web_user values ('李华',16);
ERROR 1136 (21S01): Column count doesn't match value count at row 1

Esto se debe a que cuando insertamos, no le dijimos explícitamente a MySQL qué columnas son estos dos valores. ¿Li Hua menciona el nombre o el género? ¡MySQL no tiene forma de decidir por sí mismo! Así que simplemente rechace insertarlo.

Por lo tanto, cuando queremos que una determinada columna use el valor predeterminado, debemos decirle a MySQL qué columnas de datos son los valores que estamos especificando actualmente.

insert into web_user (name,age) values ('李华',16);

Solo así la inserción podrá tener éxito.

MariaDB [hello]> insert into web_user (name,age) values ('李华',16);
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from web_user;
+-----------------+-----+--------+
| name            | age | gender |
+-----------------+-----+--------+
| 默认用户名      |   0 | 男     |
| 李华            |  16 | 男     |
+-----------------+-----+--------+
2 rows in set (0.001 sec)

Debido a que los nombres de las columnas se muestran y especifican aquí, el orden no necesariamente debe seguir el orden de los nombres de las columnas en la tabla. Por ejemplo, a continuación también podemos insertar a la inversa. Pero no se recomienda hacer esto. ¡El orden de los nombres de las columnas al insertar debe ser coherente con el orden de las columnas en la tabla!

MariaDB [hello]> insert into web_user (age,name) values (18,'小李');
Query OK, 1 row affected (0.001 sec)

MariaDB [hello]> select * from web_user;
+-----------------+-----+--------+
| name            | age | gender |
+-----------------+-----+--------+
| 默认用户名      |   0 | 男     |
| 李华            |  16 | 男     |
| 小李            |  18 | 男     |
+-----------------+-----+--------+
3 rows in set (0.001 sec)

Si desea que la columna de edad utilice el valor inicial, insértelo de la siguiente manera;

MariaDB [hello]> insert into web_user (name,gender) values ('菲菲公主','女');
Query OK, 1 row affected (0.005 sec)

2.1 Valor predeterminado y NULL

Cabe señalar que el valor predeterminado y NOT NULLno es necesario utilizarlos juntos.

  • Cuando establecemos un valor predeterminado, pero no está establecido NOT NULL, podemos insertar explícitamente NULL
  • El valor predeterminado también se puede establecer en NULL
create table if not exists test_user(
    name varchar(30) not null default '默认用户名',
    age tinyint not null default 0,
    gender char(2) default null
);

Utilice el SQL anterior para crear una tabla y la base de datos no informará ningún error, lo que significa que nuestra sintaxis es compatible. Debido a que no es necesario que el género esté involucrado en la operación, podemos pensar que cuando la columna de género está vacía, es 未选择性别la opción. Sin embargo, este problema también se puede resolver usando una cadena vacía como valor predeterminado. En comparación, usar una cadena vacía es mejor, porque esto garantiza que el valor de este campo sea siempre una cadena sin la necesidad de un manejo especial de nulo.

imagen-20230804095037098

default nully not nullno se pueden usar juntos, ¡eso es seguro!

3. Comentario de descripción de la columna.

Cabe señalar que los comentarios no son compatibles con SQLite. Las diferentes bases de datos tendrán ligeras diferencias en su compatibilidad con los campos SQL. Consulte la base de datos que está utilizando. Lo que se describe en este artículo está basado en MySQL y MariaDB.

La llamada descripción de la columna es una descripción de lo que hace la columna, lo que equivale a un comentario en el código. No tiene significado en sí mismo;

La función principal de los comentarios de columna es permitir que todos los que utilizan esta base de datos y esta tabla comprendan la función de este campo. También se pueden agregar comentarios adicionales para permitir a los programadores realizar procesamiento adicional en el código de carga de diferentes módulos.

Por ejemplo, cambiamos la tabla de usuarios que apareció en el segundo punto al siguiente formulario y agregamos comentarios a cada campo.

create table if not exists web_user(
    name varchar(30) not null default '默认用户名' comment '用户名',
    age tinyint not null default 0 comment '用户年龄',
    gender char(2) not null default '男' comment '用户性别' 
);

Después de usar este SQL para crear esta tabla, si queremos consultar los comentarios de los campos, podemos usar el siguiente comando para ver los comandos utilizados al crear la tabla (que incluye los comentarios de la tabla)

SHOW CREATE TABLE web_user;

Se muestra de la siguiente manera

MariaDB [hello]> SHOW CREATE TABLE web_user;
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                               |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| web_user | CREATE TABLE `web_user` (
  `name` varchar(30) NOT NULL DEFAULT '默认用户名' COMMENT '用户名',
  `age` tinyint(4) NOT NULL DEFAULT 0 COMMENT '用户年龄',
  `gender` char(2) NOT NULL DEFAULT '男' COMMENT '用户性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8                  |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

También puede utilizar el siguiente comando para mostrar todas las columnas y sus propiedades, incluidos los comentarios.

SHOW FULL COLUMNS FROM web_user;
MariaDB [hello]> SHOW FULL COLUMNS FROM web_user;
+--------+-------------+-----------------+------+-----+-----------------+-------+---------------------------------+--------------+
| Field  | Type        | Collation       | Null | Key | Default         | Extra | Privileges                      | Comment      |
+--------+-------------+-----------------+------+-----+-----------------+-------+---------------------------------+--------------+
| name   | varchar(30) | utf8_general_ci | NO   |     | 默认用户名      |       | select,insert,update,references | 用户名       |
| age    | tinyint(4)  | NULL            | NO   |     | 0               |       | select,insert,update,references | 用户年龄     |
| gender | char(2)     | utf8_general_ci | NO   |     | 男              |       | select,insert,update,references | 用户性别     |
+--------+-------------+-----------------+------+-----+-----------------+-------+---------------------------------+--------------+
3 rows in set (0.002 sec)

Cabe señalar que los resultados que muestra el comando desc no incluyen comentarios de columna.

MariaDB [hello]> desc web_user;
+--------+-------------+------+-----+-----------------+-------+
| Field  | Type        | Null | Key | Default         | Extra |
+--------+-------------+------+-----+-----------------+-------+
| name   | varchar(30) | NO   |     | 默认用户名      |       |
| age    | tinyint(4)  | NO   |     | 0               |       |
| gender | char(2)     | NO   |     | 男              |       |
+--------+-------------+------+-----+-----------------+-------+
3 rows in set (0.001 sec)

imagen-20230804101749987

4.relleno cero

4.1 Resultados de la prueba

Primero, cree una tabla usando el siguiente comando

create table if not exists test_int(
	a int not null,
	b int unsigned not null
);

Una vez completada la creación, observamos las declaraciones utilizadas para crear esta tabla y encontraremos que hay un corchete adicional después de int, seguido de un número.

Sabemos que en char y varchar, los corchetes se usan para limitar la longitud de los caracteres de la cadena, entonces, ¿qué se usan los corchetes para dar forma?

MariaDB [hello]> show create table test_int;
+----------+------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                           |
+----------+------------------------------------------------------------------------------------------------------------------------+
| test_int | CREATE TABLE `test_int` (
  `a` int(11) NOT NULL,
  `b` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

Primero inserte un dato en esta tabla y consulte para mostrarlo.

MariaDB [hello]> insert into test_int values (3,1);
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from test_int;
+---+---+
| a | b |
+---+---+
| 3 | 1 |
+---+---+
1 row in set (0.000 sec)

Si modificamos los atributos de la columna a al siguiente tipo de campo

alter table test_int change a a int(5) unsigned zerofill;

Verifique el comando para crear la tabla nuevamente, el resultado es el siguiente, la columna a ha sido modificada al atributo de la letra.

MariaDB [hello]> alter table test_int change a a int(5) unsigned zerofill;
Query OK, 1 row affected (0.005 sec)               
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [hello]> show create table test_int;
+----------+---------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------+
| test_int | CREATE TABLE `test_int` (
  `a` int(5) unsigned zerofill DEFAULT NULL,
  `b` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+---------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

Entonces, ¿qué hace el número entre paréntesis con zerofill?

Consulte esta tabla nuevamente y encontrará que los datos que acaba de insertar han cambiado a 3 en la columna a 00003.

MariaDB [hello]> select * from test_int;
+-------+---+
| a     | b |
+-------+---+
| 00003 | 1 |
+-------+---+
1 row in set (0.000 sec)

4.2 relleno con 0

En este momento, la función de este atributo es muy clara: se utiliza para rellenar el número con 0 y 5 es la longitud especificada del relleno de 0, no la longitud del número; cuando el número de dígitos es inferior a 5, activará el pad 0;

Se puede ver que incluso si aparece en la estructura de la tabla int(5), aún podemos insertar números de más de 5 dígitos en esta tabla.

MariaDB [hello]> insert into test_int values (12345678,1);
Query OK, 1 row affected (0.005 sec)

Por lo tanto, este corchete no se usa para limitar la longitud de int, pero cuando un número tiene menos de 5 dígitos, se agregará 0 al frente del número.

MariaDB [hello]> insert into test_int values (18,3);
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from test_int;
+----------+---+
| a        | b |
+----------+---+
|    00003 | 1 |
| 12345678 | 1 |
|    00018 | 3 |
+----------+---+
3 rows in set (0.001 sec)

Si int(5) zerofilllo cambia a un valor más largo, la longitud del 0 inicial cambiará.

alter table test_int change a a int(7) unsigned zerofill;
MariaDB [hello]> alter table test_int change a a int(7) unsigned zerofill;
Query OK, 0 rows affected (0.007 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [hello]> select * from test_int;
+----------+---+
| a        | b |
+----------+---+
|  0000003 | 1 |
| 12345678 | 1 |
|  0000018 | 3 |
+----------+---+
3 rows in set (0.001 sec)

Cabe señalar que int(n)el atributo de zerofillsolo activará la operación de agregar 0 antes de usarlo junto con . Esto puede explicar por qué el número en la tabla creada inicialmente int(11)no se completa con ceros;

El 0 antepuesto aquí es solo una optimización que se muestra internamente en MySQL . De hecho, el número en sí todavía está almacenado; por ejemplo, si consultamos 3 en la tabla anterior, podemos encontrarlo directamente.

MariaDB [hello]> select * from test_int where a = 3;
+---------+---+
| a       | b |
+---------+---+
| 0000003 | 1 |
+---------+---+
1 row in set (0.001 sec)

Por ejemplo, los números que quiero almacenar son todos de 5 dígitos, y si se configuran los 0 iniciales, los resultados de salida formateados que se ven al consultar la tabla completa se verán mucho más cómodos que los resultados sin 0 iniciales.

4.3 ¿Por qué int 11 y unsigned 10?

Al consultar la declaración de creación de tabla i predeterminada anteriormente, encontrará que el sistema MySQL tiene por defecto 11 bits para int y 10 bits para unsigned int.

imagen-20230804104708752

Esto se debe a que la longitud de 10 bits ya puede identificar todos los valores en el rango int, y los enteros con signo tienen un bit más, que se utiliza para mostrar los signos positivos y negativos.

5.clave primaria

La clave principal se usa para restringir los datos en el campo. No se puede repetir ni vaciar . Una tabla tiene solo una clave principal (o ninguna), y generalmente se usa un número entero como clave principal.

La clave principal se utiliza para determinar la unicidad de cada registro en la tabla e informa al usuario que si desea insertar datos en esta tabla, debe asegurarse de que los valores de la clave principal no entren en conflicto.

5.1 Tipos de diseño de claves primarias

Tome un sistema de usuario como ejemplo.

  • Podemos establecer el nombre de usuario como clave principal. Cuando el usuario selecciona un nombre de usuario existente, rechaza el nombre de usuario e informa al usuario;
  • Podemos usar otro número no relacionado como clave principal. Por ejemplo, QQ usa el número QQ para identificar la unicidad del usuario. No requiere que el nombre de usuario del usuario no pueda ser el mismo (la mayoría del software de chat ahora usa este método, como como QQ y KOOK, aunque WeChat no tiene un identificador único como QQ, debe haber una clave principal como identificador único en segundo plano),
  • Podemos combinar varias columnas en una clave primaria compuesta.

5.2 Eliminar y agregar claves primarias

Al crear una tabla, puede especificar la clave principal de dos maneras:

-- 方法1,在字段后指明
create table test_pri_1(
	id int unsigned not null primary key,
    name varchar(30) not null
);
-- 方法2,在表的最后指明
create table test_pri_2(
	id int unsigned not null,
    name varchar(30) not null,
    primary key(id)
);

Ambos se pueden ejecutar con éxito.

Además, la clave principal en sí no puede estar vacía, por lo que no es necesario escribirla al definir la columna de clave principal.not null

MariaDB [hello]> create table test_pri_1(
    -> id int unsigned not null primary key,
    ->     name varchar(30) not null
    -> );
Query OK, 0 rows affected (0.017 sec)

MariaDB [hello]> create table test_pri_2(
    -> id int unsigned not null,
    ->     name varchar(30) not null,
    ->     primary key(id)
    -> );
Query OK, 0 rows affected (0.019 sec)

Y la estructura de la tabla es la misma: puede ver PRI en la clave de la columna de identificación, que es Primaryla abreviatura de, lo que significa que la columna de identificación es la clave principal.

MariaDB [hello]> desc test_pri_1;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | NO   | PRI | NULL    |       |
| name  | varchar(30)      | NO   |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.001 sec)

MariaDB [hello]> desc test_pri_2;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | NO   | PRI | NULL    |       |
| name  | varchar(30)      | NO   |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.001 sec)

Si es una tabla existente, también podemos agregarle claves primarias o eliminar claves primarias.

alter table 表名 drop primary key;
-- 用于删除主键列的主键属性,因为主键列只能有一个
-- 注意,这个语句不会删除该列
alter table 表名 add primary key(id);
-- 给id列加上主键属性(但是ID列里面不能有重复值)

Pruébelo y podrá ver que el atributo PRI de la columna de identificación desapareció.

MariaDB [hello]> alter table test_pri_1 drop primary key;
Query OK, 0 rows affected (0.010 sec)              
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [hello]> desc test_pri_1;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | NO   |     | NULL    |       |
| name  | varchar(30)      | NO   |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.002 sec)

Cuando insertamos datos en la tabla, si queremos insertar el mismo registro en la columna de clave principal, MySQL rechazará la inserción.

MariaDB [hello]> insert into test_pri_2  values (1,'李华');
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> insert into test_pri_2  values (1,'李明');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

5.3 Clave primaria compuesta

Una tabla tiene solo una clave principal, pero la clave principal puede tener más de una columna ;

Tome el robot de estadísticas de actividad que escribí yo mismo como ejemplo. El robot está en diferentes servidores y recibirá diferentes ID de servidor y operaciones de diferentes usuarios. Para registrar la actividad de diferentes usuarios en diferentes servidores, en la tabla de estadísticas de usuario, usted Necesito tanto el ID del servidor como el ID del usuario; en este momento, un usuario se unirá a dos servidores y ambos servidores usarán mi robot. Cuando se retroalimenta a la tabla, una ID de usuario aparece dos veces, pero las ID de servidor correspondientes son diferentes;

En este caso, definitivamente no es posible establecer el ID de usuario o el ID del servidor como clave principal únicamente. Podemos configurar la ID de usuario y la ID del servidor para que coincidan con la clave principal;

Después de configurar la clave primaria compuesta, podemos tener la misma ID de servidor y la misma ID de usuario. Pero sólo puede ser un usuario de un determinado servidor y no puede haber dos registros con el mismo ID de servidor y de usuario . ¡Para eso están las claves primarias compuestas!

create table user(
	guild_id int unsigned comment '服务器ID',
	user_id int unsigned not null comment '用户ID',
	score tinyint unsigned not null default 0 comment '用户积分',
	primary key(guild_id, user_id) -- guild_id + user_id 为复合主键
);

Si observa la estructura de la tabla en este momento, encontrará que los dos valores clave de la identificación del servidor y la identificación del usuario tienen atributos en Key PRI, es decir, ambas son claves principales;

Además, incluso si el nuestro guild_idno está especificado not null, su NULLatributo sigue siendo NO. ¡Porque no se permite que la clave principal sea NULL!

MariaDB [hello]> create table user(
    -> guild_id int unsigned comment '服务器ID',
    -> user_id int unsigned not null comment '用户ID',
    -> score tinyint unsigned not null default 0 comment '用户积分',
    -> primary key(guild_id, user_id) -- guild_id + user_id 为复合主键
    -> );
Query OK, 0 rows affected (0.011 sec)

MariaDB [hello]> desc user;
+----------+---------------------+------+-----+---------+-------+
| Field    | Type                | Null | Key | Default | Extra |
+----------+---------------------+------+-----+---------+-------+
| guild_id | int(10) unsigned    | NO   | PRI | NULL    |       |
| user_id  | int(10) unsigned    | NO   | PRI | NULL    |       |
| score    | tinyint(3) unsigned | NO   |     | 0       |       |
+----------+---------------------+------+-----+---------+-------+
3 rows in set (0.003 sec)

Cuando insertamos, la identificación del servidor y la identificación del usuario se pueden repetir en sus respectivas columnas.

MariaDB [hello]> insert into user values (1,1,0);
Query OK, 1 row affected (0.008 sec)

MariaDB [hello]> insert into user values (1,2,0);
Query OK, 1 row affected (0.008 sec)

MariaDB [hello]> insert into user values (2,1,0);
Query OK, 1 row affected (0.001 sec)

Pero si desea insertar otro registro de este tipo basándose en el registro existente con ID de servidor 1 y ID de usuario 1 , se informará un error y se rechazará la inserción.

MariaDB [hello]> select * from user;
+----------+---------+-------+
| guild_id | user_id | score |
+----------+---------+-------+
|        1 |       1 |     0 |
|        1 |       2 |     0 |
|        2 |       1 |     0 |
+----------+---------+-------+
3 rows in set (0.000 sec)

MariaDB [hello]> insert into user values (1,1,10);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

6.incremento_automático

El incremento automático, como sugiere el nombre, significa que MySQL agregará automáticamente datos a esta columna por nosotros. Por ejemplo, para un número de serie, agregar un nuevo registro aumentará el número de serie en uno; ¡los atributos de incremento automático solo se pueden agregar al modelado!

¡La columna de incremento automático debe ser la clave principal!

6.1 Uso

La forma de utilizar el incremento automático es agregar esta restricción después de crear el valor clave de la tabla.

create table test_pri_3(
	id int unsigned auto_increment,
    name varchar(30) not null,
    primary key(id)
);

Al observar la estructura de la tabla, puede ver que la columna de identificación es la clave principal, no está vacía y tiene un atributo de incremento automático.

MariaDB [hello]> desc test_pri_3;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30)      | NO   |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.003 sec)

Dado que la columna de incremento automático debe ser la clave principal, no podemos usarla por separado de la clave principal;

Si esta columna no se establece como clave principal al configurar el incremento automático, se informará un error al crear la tabla.

MariaDB [hello]> create table test_pri_4(
    -> id int unsigned auto_increment,
    ->     name varchar(30) not null
    -> );
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

Después de configurar el incremento automático, también podemos especificar explícitamente el valor de la columna; también podemos insertar datos directamente de otras columnas sin especificarlo. MySQL nos ayudará automáticamente a hacer +1 en el registro actual.

MariaDB [hello]> insert into test_pri_3 values (1,'李华');
Query OK, 1 row affected (0.007 sec)

MariaDB [hello]> select * from test_pri_3;
+----+--------+
| id | name   |
+----+--------+
|  1 | 李华   |
+----+--------+
1 row in set (0.001 sec)

MariaDB [hello]> insert into test_pri_3 (name) values ('小明');
Query OK, 1 row affected (0.001 sec)

MariaDB [hello]> select * from test_pri_3;
+----+--------+
| id | name   |
+----+--------+
|  1 | 李华   |
|  2 | 小明   |
+----+--------+
2 rows in set (0.000 sec)

Inserte algunos datos más y podrá ver que la columna de ID se ha incrementado correctamente.

MariaDB [hello]> insert into test_pri_3 (name) values ('小明3');
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> insert into test_pri_3 (name) values ('小明5');
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from test_pri_3;
+----+---------+
| id | name    |
+----+---------+
|  1 | 李华    |
|  2 | 小明    |
|  3 | 小明3   |
|  4 | 小明5   |
+----+---------+
4 rows in set (0.000 sec)

6.2 ¿Cómo determina el incremento automático la posición actual del número de serie?

¿La longitud que aumenta automáticamente comienza desde el número más grande? ¿O existen otros procedimientos de procesamiento?

Primero intente insertar activamente un valor clave de 1000 en la tabla y luego inserte dos filas de registros sin especificar la identificación.

MariaDB [hello]> insert into test_pri_3 values (1000,'test');
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> insert into test_pri_3 (name) values ('test1');
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> insert into test_pri_3 (name) values ('test2');
Query OK, 1 row affected (0.001 sec)

Si consulta la lista, encontrará que todos los registros posteriores a 1000 se agregan a partir de 1000.

MariaDB [hello]> select * from test_pri_3;
+------+---------+
| id   | name    |
+------+---------+
|    1 | 李华    |
|    2 | 小明    |
|    3 | 小明3   |
|    4 | 小明5   |
| 1000 | test    |
| 1001 | test1   |
| 1002 | test2   |
+------+---------+
7 rows in set (0.000 sec)

¿Podría ser que se incremente automáticamente en función del ID más grande? Intentemoslo de nuevo.

Primero elimine el registro con el ID más grande y luego inserte nuevos datos.

MariaDB [hello]> delete from test_pri_3 where id = 1002;
Query OK, 1 row affected (0.007 sec)

MariaDB [hello]> insert into test_pri_3 (name) values ('test3');
Query OK, 1 row affected (0.006 sec)

Vuelva a consultar y encontrará que el ID de incremento automático es 1003. Se puede ver que el valor máximo de una identificación registrada internamente se incrementa automáticamente de acuerdo con un registro interno adicional, en lugar de juzgar el valor máximo de la columna de identificación en la tabla.

MariaDB [hello]> select * from test_pri_3;
+------+---------+
| id   | name    |
+------+---------+
|    1 | 李华    |
|    2 | 小明    |
|    3 | 小明3   |
|    4 | 小明5   |
| 1000 | test    |
| 1001 | test1   |
| 1003 | test3   |
+------+---------+
7 rows in set (0.001 sec)

Entonces, ¿dónde está este récord extra?

show create table test_pri_3;

Utilice el comando anterior para ver la instrucción SQL que crea la tabla. Encontrará que inmediatamente después de la tabla, hay un campo de incremento automático.AUTO_INCREMENT=1004

MariaDB [hello]> show create table test_pri_3;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                              |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_pri_3 | CREATE TABLE `test_pri_3` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1004 DEFAULT CHARSET=utf8 |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

Esta es la definición del valor actual del campo de incremento automático en MySQL. Lo que se almacena aquí es el valor de incremento automático del siguiente registro insertado y su identificación. Cada vez que se inserta un nuevo registro, el valor de incremento automático aquí se convertirá en el valor que debería tener el siguiente registro;

Por ejemplo, si queremos que el ID de un sistema aumente de 10001, podemos insertar directamente un registro con un ID de 10000 en la tabla después de crearla. Para otros registros creados después de esto, el ID aumentará de 10001.

imagen-20230804133951367

6.3 Índice

Hablando de eso, permítanme mencionar el concepto de índices en MySQL.

Índice : en una base de datos relacional, un índice es una estructura de almacenamiento física separada que ordena los valores de una o más columnas en una tabla de base de datos. Es una colección de uno o más valores de columna en una tabla y una lista correspondiente de punteros lógicos a páginas de datos en la tabla que identifican físicamente estos valores .

El índice es equivalente a la tabla de contenido de un libro . Puede encontrar rápidamente el contenido requerido según los números de página en la tabla de contenido. Los índices proporcionan punteros a valores de datos almacenados en columnas específicas de una tabla y luego clasifican estos punteros según el orden de clasificación que usted especifique. La base de datos utiliza un índice para encontrar un valor específico y luego apunta hacia adelante para encontrar la fila que contiene ese valor.

Esto permite que las declaraciones SQL correspondientes a la tabla se ejecuten más rápido y permite un acceso rápido a información específica en la tabla de la base de datos.

La indexación es esencialmente una rutina que intercambia espacio por tiempo. En el negocio actual de múltiples concurrencias, la velocidad de ejecución es mucho más importante que el uso de memoria y disco.

7. clave única única

La restricción de la clave única en el campo es que los datos de esta columna no pueden ser los mismos.

Parece similar a la clave principal, pero en realidad es una restricción única independiente de la clave principal. La diferencia con la clave principal es que la clave única puede ser NULL

Ya sabes, solo se puede configurar una clave principal en una tabla. Las claves primarias compuestas a veces no satisfacen nuestras necesidades. Por lo tanto, MySQL proporciona restricciones de clave única adicionales además de la clave principal, lo que nos permite establecer la unicidad para otras columnas.

¿En cuanto a por qué? Es como un descargo de responsabilidad: los datos de mi columna están configurados para ser únicos, por lo que es imposible aceptar dos registros idénticos (por ejemplo, dos personas en la tabla de usuarios tienen el mismo número de teléfono móvil, lo cual no está permitido). aparece en su negocio Si ocurre un error cuando se rechaza la inserción, entonces debe mirar el ERROR en el código de procesamiento comercial en lugar de culpar a MySQL por no mantener la unicidad o negarse a insertar registros.

7.1 Claves individualmente únicas

Supongamos que tengo una plataforma que utiliza un número QQ como clave principal del usuario similar a QQ; pero para la autenticación de nombre real, requerimos que una tarjeta de identificación solo pueda registrar una cuenta. En este momento, no podemos usar una clave primaria compuesta para resolver este problema, porque la clave primaria compuesta permite que una de las columnas se repita ; y lo que necesitamos es que el número de cuenta de usuario y el número de identificación de usuario no se puedan repetir.

Al mismo tiempo, en la información de contacto del usuario, los números de teléfono y los ID de WeChat de los dos usuarios no deben ser los mismos. Si desea agregar el valor clave del número de teléfono, ¡también puede configurarlo unique!

En este momento, el número de usuario se puede utilizar como clave principal y el número de identificación de usuario se puede configurar uniquecomo clave única;

create table test_unique_1(
	no int unsigned not null primary key,
	name varchar(30) not null,
    id_card varchar(30) not null unique 
);

Vea la estructura de la tabla, la columna de clave única, la restricción de clave es UNI, que es uniquela abreviatura de

MariaDB [hello]> desc test_unique_1;
+---------+------------------+------+-----+---------+-------+
| Field   | Type             | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| no      | int(10) unsigned | NO   | PRI | NULL    |       |
| name    | varchar(30)      | NO   |     | NULL    |       |
| id_card | varchar(30)      | NO   | UNI | NULL    |       |
+---------+------------------+------+-----+---------+-------+
3 rows in set (0.001 sec)

id_cardCuando insertamos el mismo registro en la columna de clave principal o en la columna de esta tabla , MySQL rechazará la inserción.

MariaDB [hello]> insert into test_unique_1 values (1,'李华',123456);
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> insert into test_unique_1 values (1,'李华',1234567);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

MariaDB [hello]> insert into test_unique_1 values (3,'小明',123456);
ERROR 1062 (23000): Duplicate entry '123456' for key 'id_card'

7.2 Claves únicas compuestas

Una clave única también puede establecer varias columnas y el efecto es el mismo que el de una clave primaria compuesta; no se explicará aquí.

create table user(
	user_no int unsigned primary key auto_increment comment '用户编号 主键',
	guild_id int unsigned comment '服务器ID',
	user_id int unsigned not null comment '用户ID',
	score tinyint unsigned not null default 0 comment '用户积分',
	unique(guild_id, user_id) -- guild_id + user_id 为复合唯一键
);

Las restricciones de los pares de la tabla guild_id和user_idse convierten en MUL, como se muestra en la siguiente figura;

Se puede observar que guild_iddebido a que no hay configuración not null, la columna NULL es SÍ, lo que significa que esta columna puede ser NULL (la clave única puede ser NULL, pero la clave principal no)

MUL significa que actualmente se permite que varias filas tengan el mismo valor en esta columna, pero guild_id和user_idno se permite que existan dos filas iguales.

MariaDB [hello]> desc user;
+----------+---------------------+------+-----+---------+----------------+
| Field    | Type                | Null | Key | Default | Extra          |
+----------+---------------------+------+-----+---------+----------------+
| user_no  | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| guild_id | int(10) unsigned    | YES  | MUL | NULL    |                |
| user_id  | int(10) unsigned    | NO   |     | NULL    |                |
| score    | tinyint(3) unsigned | NO   |     | 0       |                |
+----------+---------------------+------+-----+---------+----------------+
4 rows in set (0.001 sec)

Como se muestra a continuación, la última inserción es la misma que la primera guild_id和user_id, por lo que se produce un error de rechazo de inserción.

MariaDB [hello]> insert into user values (1,1,1,20);
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> insert into user values (2,1,2,21);
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> insert into user values (3,2,3,22);
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> insert into user values (4,1,1,23);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'guild_id'

7.3 ¿Qué son MUL, PRI y UNI en MySQL?

De la documentación del sitio web oficial de Mysql 5.7 :

  • Si la clave es un PRI, la columna es la clave principal o una de las columnas de una clave principal de varias columnas;
  • Si la clave es UNI, esta columna es la primera columna del índice único (los índices únicos permiten múltiples valores nulos, pero puede determinar si la columna permite nulos marcando el campo NULL);
  • Si la clave es MUL, la columna es la primera columna en un índice no único, donde se permiten múltiples apariciones de un valor determinado en la columna;

8.Claves externas

8.1 Descripción

Las claves externas se utilizan para definir la relación entre ciertos campos en dos tablas y para restringir registros;

La sintaxis básica es la siguiente y se utiliza al crear tablas. ¡La tabla donde se establece la clave externa es la tabla esclava!

foreign key (字段名) references 主表()

Por ejemplo, en la figura siguiente, el número de clase de cada estudiante en la tabla de estudiantes corresponde al ID de clase en la tabla de clases. En este momento, podemos configurar el ID de la tabla de clases como una clave externa en la tabla de estudiantes class_id;

Aunque podemos insertar los datos de la tabla de clases directamente en la tabla de estudiantes, esto no es razonable. Si tenemos muchos campos para una clase o un estudiante, es muy inconveniente combinar estas dos tablas. Debido a que hay muchos estudiantes en la misma clase, después de fusionar las tablas, es equivalente a los estudiantes de la misma clase y la información en las columnas de su clase es toda igual , lo que resulta en una ocupación de recursos sin sentido (redundancia).

Por el contrario, después de dividir las tablas, es una mejor opción utilizar claves externas para vincular los dos campos .

imagen-20230804161621345

En la situación anterior, myclass es la tabla maestra y stu es una tabla esclava;

-- 主表 班级
create table myclass (
	id int primary key comment '班级号',
	name varchar(30) not null comment '班级名'
);
-- 从表 学生
create table stu (
	id int primary key,
	name varchar(30) not null comment '学生名',
	class_id int,
	foreign key (class_id) references myclass(id) -- 设置从表外键约束
);

8.2 Pruebas

Después de crear la tabla, primero echemos un vistazo a los atributos de la tabla de estudiantes i. Puede ver que la class_idclave de la tabla es MUL, que es la misma que cuando se configuró la clave única compuesta anteriormente.

MariaDB [hello]> desc stu;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int(11)     | NO   | PRI | NULL    |       |
| name     | varchar(30) | NO   |     | NULL    |       |
| class_id | int(11)     | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.001 sec)

Cuando intentamos insertar datos en la tabla de estudiantes, se informará un error.

MariaDB [hello]> insert into stu values (1,'李华',2);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`hello`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

Esto se debe a que en el registro que estableció, la clase número 2 del estudiante no existe en absoluto en la tabla de clases. ¿Cómo puede una clase que no existe tener estudiantes? Por lo que naturalmente rechaza su inserción.

Por lo tanto, si queremos insertar un estudiante, debemos asegurarnos de que la clase donde se encuentra el registro del estudiante exista en la tabla de clases. De esta manera, se logra la vinculación N a 1 de estudiantes y clases.

MariaDB [hello]> insert into myclass values (1,'少华班');
Query OK, 1 row affected (0.002 sec)

MariaDB [hello]> insert into stu values (1,'李华',1);
Query OK, 1 row affected (0.005 sec)

MariaDB [hello]> select * from myclass;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 少华班    |
+----+-----------+
1 row in set (0.001 sec)

MariaDB [hello]> select * from stu;
+----+--------+----------+
| id | name   | class_id |
+----+--------+----------+
|  1 | 李华   |        1 |
+----+--------+----------+
1 row in set (0.000 sec)

Aquí he insertado algunos datos más.

MariaDB [hello]> select * from stu;
+----+-----------+----------+
| id | name      | class_id |
+----+-----------+----------+
|  1 | 李华      |        1 |
|  2 | 小明      |        1 |
|  3 | 小流      |        1 |
|  4 | 小流2     |        2 |
|  5 | 猪猪侠    |        2 |
|  6 | 苗条俊    |        2 |
+----+-----------+----------+
6 rows in set (0.000 sec)

MariaDB [hello]> select * from myclass;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 少华班    |
|  2 | 你好班    |
+----+-----------+
2 rows in set (0.000 sec)

Hay otra pregunta en este momento: si hay estudiantes en esta clase, ¿podemos eliminar esta clase?

Pensándolo bien, definitivamente no es posible: como no existe tal clase, no se puede insertar al estudiante correspondiente. Luego, cuando haya estudiantes en esta clase, no debes eliminar la clase. Los dos son mutuamente lógicos, lo mismo ocurre en MySQL: cuando una clase tiene estudiantes correspondientes, no se permite la eliminación.

MariaDB [hello]> delete from myclass where id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`hello`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

¡Solo cuando no haya más estudiantes en esta clase se podrá eliminar de la tabla de clases!

MariaDB [hello]> delete from stu where class_id = 2;
Query OK, 3 rows affected (0.005 sec)

MariaDB [hello]> delete from myclass where id = 2;
Query OK, 1 row affected (0.006 sec)

MariaDB [hello]> 

Tampoco se permite actualizar el ID de la clase porque hay estudiantes vinculados a esta clase en la tabla de estudiantes. MySQL no puede ayudarnos a actualizar directamente los números de clase de todos los estudiantes.

MariaDB [hello]> update  myclass set id = 3 where name = '你好班'; 
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`hello`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

8.3 Restricciones de clave externa

En la situación anterior, podemos establecer completamente dos tablas independientes sin relaciones de clave externa y mantener la relación entre las dos en la capa de código.

Pero de esta manera, las operaciones de estas dos tablas siguen siendo independientes . MySQL no sabe que existe una conexión entre las dos tablas, en este momento puede insertar estudiantes en clases que no existen y eliminar clases que aún tienen estudiantes. Si lo dejas caer, eventualmente se convertirá en un desastre ;

  • Automantenimiento: la información de las dos tablas está relacionada
  • Más claves externas: restricciones de MySQL

¡La combinación de los dos es la clave externa completa!

Es por eso que necesitamos definir restricciones de clave externa entre estas dos tablas en MySQL y dejar que MySQL nos ayude a mantener la relación de datos en las dos tablas.

Nota: Aunque MySQL restringirá nuestras operaciones en este momento, el programador aún debe manejar el proceso comercial real en el código. Por ejemplo, no inserte estudiantes cuyas clases no existan en MySQL (MySQL solo rechazará la inserción y no podrá ayudarle a corregir la clase).

El fin

Estas son las operaciones de restricción básicas. ¡Hay otras que se usarán y se agregarán en el futuro!

Supongo que te gusta

Origin blog.csdn.net/muxuen/article/details/132158703
Recomendado
Clasificación