Una modesta guía de esquemas de bases de datos.


Geometría de flores de Mookiezoolook

Para aplicaciones que se escalarán de acuerdo con el tráfico y la complejidad, es extremadamente importante diseñar inicialmente un esquema de base de datos competente. Si hace una mala elección, tendrá que invertir mucho esfuerzo para que esta plantilla incorrecta no se extienda a los servicios y controladores de back-end y, finalmente, a la interfaz.

Pero, ¿cómo evaluar qué circuito es mejor? ¿Y qué significa "mejor" cuando hablamos de arquitectura de base de datos? El equipo de Mail.ru Cloud Solutions lo invita a seguir las recomendaciones de Mike Alcha , un consultor de desarrollo de software. Nos parece que resumió sucintamente algunos principios de arquitectura competente.


Director: " Creo que deberíamos construir una base de datos SQL " .

Desarrollador (¿comprende siquiera de qué está hablando o simplemente vio algún tipo de anuncio en una revista de negocios? ...): " ¿ De qué color quieres la base de datos? ".

Director: " Quizás la lila tiene más memoria " .

Algunos consejos básicos


Por lo tanto, es importante luchar por dos cosas principales :

  1. Al dividir la información en tablas, toda la información se almacena.
  2. La redundancia de almacenamiento es mínima.

En cuanto al segundo punto: ¿queremos reducir la redundancia solo por un problema con el tamaño de almacenamiento? No, hacemos esto principalmente porque la presencia de datos redundantes genera problemas de inconsistencia si no actualiza todos los campos que representan la misma información durante la actualización.

Aquí hay algunas pautas para acercarse a la buena arquitectura :

  1. Utilice al menos una tercera forma normal (en la que cada atributo no clave "debe proporcionar información sobre la clave, la clave completa y nada más que la clave", según la redacción de Bill Kent).
  2. Crea la última línea de defensa en forma de restricciones.
  3. Nunca almacene direcciones completas en un campo.
  4. Nunca almacene el nombre y apellido en un campo.
  5. Establezca convenciones para nombres de tablas y campos y cúmplalas.


- ¿En que estas trabajando?

" Optimizando esta consulta SQL". Se ralentiza y los usuarios comienzan a quejarse.

- ¿ Y se requiere un lenguaje obsceno en los comentarios para la optimización?

- Si vieras el código original , no lo preguntarías.

Consideremos estas recomendaciones con más detalle.

1. Use al menos una tercera forma normal


La arquitectura de la base de datos se puede dividir en las siguientes categorías:

  • La primera forma normal.
  • La segunda forma normal.
  • Tercera forma normal.
  • La forma normal de Boyce-Codd.

Estas categorías representan una clasificación por calidad. Revisaremos brevemente todas las categorías y veremos por qué se necesita al menos una tercera forma normal.

Primera forma normal


Para la primera forma normal, cada valor de cada columna de cada tabla en la base de datos debe ser atómico. ¿Qué significa atómico? En resumen, el valor atómico es una "cosa única".

Por ejemplo, tenemos una tabla como esta:
nombre de pilaapellidoañosáreas
JhonGama27{"Diseño de sitio web", "Investigación de clientela"}
MaríaJane33{"Planificación estratégica a largo plazo", "Reclutamiento"}
TomHerrero35{"Márketing"}

Aquí, la columna de áreas contiene valores que no son atómicos. Por ejemplo, en una línea de John Doe, el campo almacena dos entidades: diseño del sitio web e investigación del cliente.

Entonces esta tabla no está en la primera forma normal.

Para llevarlo a este formulario, solo se debe almacenar un valor en cada campo .

Segunda forma normal


En la segunda forma normal, ninguna columna que no sea parte de la clave primaria (o que pueda actuar como parte de otra clave primaria) no puede derivarse de la parte más pequeña de la clave primaria .

Qué significa eso?

Supongamos que tiene una arquitectura de base de este tipo (enfaticé los campos correspondientes a la clave primaria en esta tabla):
ID de empleadoProjecto IDHorasnombre de empleadonombre del proyecto
1110Juan"Diseño de páginas web"
21veinteMaría"Diseño de páginas web"

En este proyecto, el nombre del empleado se puede inferir directamente de employeee_id, porque la idea es que el nombre del empleado está determinado únicamente por su identificador.

Del mismo modo, el nombre del proyecto se identifica de forma exclusiva mediante el identificador project_id.

Por lo tanto, tenemos dos columnas que se pueden deducir de la parte clave principal.

Cada uno de estos ejemplos sería suficiente para sacar esta tabla de la segunda forma normal.

Otra conclusión es que si la tabla estaba en la primera forma normal y todas las claves primarias son columnas individuales, entonces la tabla ya está en la segunda forma normal.

Tercera forma normal


Para que la tabla se corresponda con la tercera forma normal, debe estar en la segunda forma normal, mientras que no debe haber ningún atributo (columnas) en ella, excepto la primaria, que dependen transitivamente de la clave primaria.

Qué significa eso?

Digamos que tiene la siguiente arquitectura (que está lejos de ser ideal):
nombre de empleadoID de empleadoañosnúmero_departamentalNombre de Departamento
Juan127123"Márketing"
María233456"Operacional"
Tom335123"Márketing"

En esta tabla, se puede inferir número_departamental a partir de id_de_empleado, y se puede inferir nombre_departamental a partir del número_departamental. ¡Así que nombre_departamental depende transitivamente de id_empleado!

Si existe una dependencia transitiva de este tipo: employee_id → department_number → department_name, esta tabla no está en la tercera forma normal.

¿Qué problemas surgen debido a esto ?

Si el nombre del departamento puede derivarse de su número, el almacenamiento de este campo para cada empleado introduce una redundancia excesiva.

Imagine que el departamento de marketing cambia su nombre a "Marketing y ventas". ¡Para mantener la coherencia, tendrá que actualizar la celda en cada fila de la tabla para cada empleado en este departamento! En la tercera forma normal, esto no habría sucedido.

Además, esto es lo que sucede si Mary decide abandonar la empresa: debemos eliminar su fila de la tabla, pero si ella era la única empleada en el departamento de operaciones, entonces el departamento también tendrá que ser eliminado.

Todos estos problemas se pueden evitar por completo en una tercera forma normal.


Las hazañas de mamá . El nombre de su hija es ¡Ayuda! Me veo obligado a falsificar pasaportes

2. Crear la última línea de defensa en forma de restricciones.


La base de datos con la que está trabajando es más que solo un grupo de tablas. Cierta funcionalidad está integrada en él. Muchas de estas características ayudan a garantizar la calidad y precisión de los datos.

Las restricciones establecen las reglas, qué valores se pueden ingresar en los campos de la base de datos.

Al definir relaciones en una base de datos, asegúrese de establecer restricciones de clave externa.

Asegúrese de especificar lo que debe suceder al eliminar y actualizar una fila asociada con otras filas en otras tablas (reglas ON DELETE y ON UPDATE).

Asegúrese de utilizar NOT NULL para todos los campos que nunca deben anularse. Puede tener sentido establecer un control en el backend, pero recuerde que los bloqueos siempre ocurren, por lo que agregar este tipo de restricción no afectará.

Establezca los límites de verificación de VERIFICACIÓN para asegurarse de que los valores de la tabla estén en el rango aceptable, por ejemplo, el precio de un producto siempre tiene un valor positivo.

Un hecho interesante : en abril de 2020, precisamente esa restricción en el software impidió cotizar en el MICEX de Moscú porque el precio de los futuros del petróleo WTI cayó por debajo de cero. A diferencia de la bolsa de valores de Moscú, la Bolsa Mercantil de Nueva York NYMEX actualizó el software una semana antes del incidente , por lo que pudo realizar transacciones con éxito a un precio negativo, es decir, con un recargo al vendedor por parte del vendedor: aprox. trans.

Todas las limitaciones de PostgreSQL se pueden encontrar aquí .

3. Nunca almacene direcciones completas en un campo


Si su aplicación o sitio web tiene un formulario con un campo donde el usuario ingresa su dirección, entonces huele mal. Es muy probable que en este caso también tenga un campo en la base de datos para almacenar la dirección como una cadena simple.

Pero, ¿qué hacer si necesita combinar las compras de los clientes por ciudad para ver qué ciudad es el producto más popular? ¿puedes hacerlo?

¡Será muy difícil!

Dado que la dirección completa se almacena como una cadena en el campo de la base de datos, ¡primero tendrá que calcular cuánto de esta cadena es la ciudad! Y esta es una tarea casi imposible, dados todos los formatos de dirección posibles en este campo.

Por lo tanto, asegúrese de dividir el campo universal "Dirección" en campos específicos: calle, número de casa, ciudad, región, código postal, etc.

Otro problema de dirección: campos anónimos


Aquí hay una ilustración del libro de Michaels Blach, The Copper Bullet para mejorar la calidad del software:


¿Qué problemas potenciales son visibles aquí? ¿Puedes distinguir fácilmente la ciudad de Chicago de las calles de Chicago? Probablemente no.

Por lo tanto, recuerde siempre dar nombres de columna claros a cada unidad de información.


Cómo escribir un currículum

- ¿Tienes experiencia en SQL?

- No (no).

- Entonces escribe: experto NoSQL.

4. Nunca almacene el nombre y apellido en un campo


Similar a la situación con las direcciones: el número de variaciones del nombre y apellido es demasiado grande para distinguirlos claramente.

Por supuesto, puede separar el nombre del apellido, si hay un espacio entre ellos.

Por ejemplo, "Mike Alche" → el nombre "Mike" y el apellido "Alche".

Pero, ¿qué pasa si el usuario ingresó un segundo nombre? ¿O tiene un apellido doble? Pero, ¿qué pasa si hay un segundo nombre y un apellido doble?

¿Cómo determinar dónde está el nombre y dónde está el apellido para dividir la cadena? Los errores son inevitables.

Una forma de evitar muchos problemas es crear campos separados (en formularios) para los nombres de usuario first_name y last_name. De esta manera, permite a los usuarios compartir sus propios nombres y puede almacenar datos de manera coherente.

Nota: No estoy diciendo que los espacios estén prohibidos en los campos de la base de datos. Por ejemplo, para nombres como Juan Martin Del Potro, la primera parte de Juan Martin está en el campo first_name y Del Potro está en el campo last_name. Por supuesto, esto no es perfecto . Opcionalmente, puede tener las columnas middle_name y second_last_name. Observe con más detalle las posibles variaciones de nombres y apellidos en la lista " Conceptos erróneos de los programadores sobre los nombres " y el artículo " Conceptos erróneos de los programadores sobre los nombres, con ejemplos ". Debe acordar algún tipo de compromiso entre precisión y practicidad.

5. Establezca convenciones para nombres de tablas y campos y cúmplalas


Es bastante molesto trabajar con datos que se parecen a user.firstName, user.lst_name, user.birthDate, etc.

Le aconsejaría que establezca reglas de nomenclatura de subrayado, porque no todos los motores SQL manejan las letras mayúsculas de la misma manera, y encerrar todo entre comillas es muy tedioso.

Elija lo mismo que llamar a las tablas, en plural o singular (por ejemplo, usuarios en plural o usuario en singular). Me gusta más el singular, pero todos los marcos de backend parecen estar en plural por defecto. Tienes que seguir el patrón y usar el plural.

¿Qué más leer ?

  1. Qué base de datos elegir para el proyecto, para que no tenga que volver a elegir .
  2. IIoT-: Mail.ru Cloud Solutions .
  3. .

All Articles