JavaRush /Blog Java /Random-ES /Parte 2. Estructura, tablas y tipos de datos del DBMS
Marat Sadykov
Nivel 41

Parte 2. Estructura, tablas y tipos de datos del DBMS

Publicado en el grupo Random-ES
Primera parte
Parte 2. Estructura, tablas y tipos de datos del DBMS - 1
Seguimos creando nuestro sencillo emulador de bolsa de valores. Esto es lo que haremos:
  • Creemos un diagrama de organización de la base de datos.
  • Describiremos qué, cómo y dónde se almacena.
  • Descubramos cómo se relacionan los datos entre sí.
  • Comencemos a aprender los conceptos básicos de SQL usando el ejemplo del comando de creación de tablas SQL CREATE TABLE , lenguaje de definición de datos ( DDL ) del lenguaje SQL.
  • Sigamos escribiendo el programa Java. Implementamos las funciones principales del DBMS en términos de java.sql para crear nuestra base de datos mediante programación, utilizando JDBC y una arquitectura de tres niveles.
Estas dos partes resultaron ser más voluminosas, ya que necesitamos familiarizarnos con los conceptos básicos de SQL y la organización de un DBMS desde adentro, y hacer analogías con Java. Para no aburrirlo con listados de códigos, al final hay enlaces al repositorio de github de confirmación correspondiente con el programa.

diseño de SGBD

Descripción de la aplicación

Ya habrás oído que organizar el almacenamiento de datos es una parte integral de la programación. Permítanme recordarles que el propósito de nuestra aplicación es la emulación de intercambio más simple:
  • Hay acciones cuyo valor puede cambiar durante el día de negociación según reglas determinadas;
  • hay comerciantes con capital inicial;
  • Los comerciantes pueden comprar y vender acciones según su algoritmo.
El intercambio opera en ticks , períodos de tiempo fijos (en nuestro caso, 1 minuto). Durante un tick, el precio de las acciones puede cambiar y luego el operador puede comprar o vender acciones.

Estructura de datos de emulación de Exchange

Llamemos modelos de entidades de intercambio individuales. Para evitar errores de redondeo, trabajaremos con importes financieros a través de una clase BigDecimal(los detalles se pueden encontrar en el enlace al final del artículo). Describamos con más detalle la estructura de cada modelo: Promoción:
Atributo Tipo Descripción
name Srting Nombre
changeProbability En t Probabilidad de cambio de tasa como porcentaje en cada tick
startPrice GranDecimal Costo inicial
delta En t La cantidad máxima en porcentaje por la cual el valor actual puede cambiar
Precio de la acción:
Atributo Tipo Descripción
operDate Fecha y hora local Tiempo (tick) para fijar la tarifa
share Promoción Enlace a la promoción
rate GranDecimal Precio de la acción
Comerciante:
Atributo Tipo Descripción
name Cadena Tiempo (tick) para fijar la tarifa
sfreqTick En t Frecuencia de transacciones. Especificado por el período, en ticks, después del cual el comerciante realiza operaciones
cash GranDecimal Cantidad de dinero distinta de acciones
traidingMethod En t El algoritmo utilizado por el comerciante. Configurémoslo como un número constante, la implementación del algoritmo será (en las siguientes partes) en código Java
changeProbability En t Probabilidad de completar la operación, porcentaje.
about Cadena Probabilidad de cambio de tasa, en porcentaje, en cada tick
Acciones del comerciante:
Atributo Tipo Descripción
operation En t Tipo de transacción (compra o venta)
traider Comerciante Enlace comerciante
shareRate Precio de la acción Enlace al precio de las acciones (respectivamente, la acción en sí, su tasa y el momento de su emisión)
amount Largo Número de acciones involucradas en la transacción
Para garantizar la singularidad de cada modelo, agregaremos un atributo idde tipo long . Este atributo será único dentro de las instancias del modelo y lo identificará de forma única. Los atributos que hacen referencia a otros modelos (comerciante, acción, precio de la acción) pueden usar este idpara identificar de forma única el modelo correspondiente. Inmediatamente nos viene a la mente la idea de que podríamos utilizar Map<Long, Object> para almacenar dichos datos, ¿dónde Objectestá el modelo correspondiente? Sin embargo, intente implementar esto en código bajo las siguientes condiciones:
  • el tamaño de los datos supera significativamente la cantidad de RAM disponible;
  • se espera acceso a los datos desde una docena de lugares diferentes;
  • se requiere la capacidad de modificar y leer datos simultáneamente;
  • es necesario garantizar reglas para la formación e integridad de los datos;
...y se enfrentará a tareas que requieren calificaciones y tiempo adecuados para implementarlas. No es necesario “reinventar la rueda”. Ya se ha pensado y escrito mucho para nosotros. Por eso utilizaremos lo que ya se ha probado a lo largo de los años.

Almacenamiento de datos en Java

Consideremos la acción. En Java, creamos una clase específica para este modelo Sharecon campos name,,,, . Y muchos recursos compartidos se almacenaron como , donde la clave es un identificador único para cada recurso compartido. changeProbabilitystartPricedeltaMap<Long, Share>
public class Share {
    private String name;
    private BigDecimal startPrice;
    private int changeProbability;
    private int delta;
}
Map<Long, Share> shares = new HashMap<>();
shares.put(1L, new Share("ibm", BigDecimal.valueOf(20.0), 15, 10));
shares.put(2L, new Share("apple", BigDecimal.valueOf(14.0), 25, 15));
shares.put(3L, new Share("google", BigDecimal.valueOf(12.0), 20, 8));
...
shares.put(50L, new Share("microsoft", BigDecimal.valueOf(17.5), 10,4 ));
Para acceder a la promoción deseada por ID utilice el método shares.get(id). Para la tarea de encontrar una acción por nombre o precio, recorreríamos todos los registros buscando la que necesitamos, y así sucesivamente. Pero iremos por el otro lado y almacenaremos los valores en el DBMS.

Almacenamiento de datos en un DBMS

Formulemos un conjunto inicial de reglas de almacenamiento de datos para un DBMS:
  • Los datos en un DBMS se organizan en tablas ( TABLE ), que son un conjunto de registros.
  • Todos los registros tienen los mismos conjuntos de campos. Se configuran al crear la tabla.
  • El campo se puede establecer en un valor predeterminado ( DEFAULT ).
  • Para una tabla, puede establecer restricciones ( CONSTRAINT ) que describen los requisitos de sus datos para garantizar su integridad. Esto se puede hacer en la etapa de creación de la tabla ( CREATE TABLE ) o agregarlo más tarde ( ALTER TABLE ... ADD CONSTRAINT ).
  • La RESTRICCIÓN más común :
    • La clave principal es PRIMARIA (Id en nuestro caso).
    • Campo de valor único ÚNICO (VIN para la tabla de vehículos).
    • Comprobando el campo VERIFICAR (el valor porcentual no puede ser mayor que 100). Una de las restricciones privadas en un campo es NOT NULL o NULL , lo que prohíbe/permite almacenar NULL en un campo de tabla.
    • Enlace a una tabla de terceros FOREIGN KEY (enlace a una acción en la tabla de precios de acciones).
    • Index INDEX (indexar un campo para acelerar la búsqueda de valores en él).
    • La modificación de un registro ( INSERT , UPDATE ) no ocurrirá si los valores de sus campos contradicen las restricciones (CONSTRAINT).
  • Cada tabla puede tener un campo clave (o varios) que se pueden utilizar para identificar de forma única un registro. Dicho campo (o campos, si forman una clave compuesta) forma la clave principal de la tabla: PRIMARY KEY .
    • La clave principal garantiza la unicidad de un registro en la tabla; se crea un índice en ella, lo que brinda acceso rápido a todo el registro en función del valor de la clave.
    • Tener una clave principal hace que sea mucho más fácil crear vínculos entre tablas. A continuación, usaremos una clave primaria artificial: para el primer registro id = 1, cada registro posterior se insertará en la tabla con el valor de identificación aumentado en uno. Esta clave suele denominarse AutoIncrement o AutoIdentity .
En realidad, una tabla de acciones: Parte 2. Estructura, tablas y tipos de datos del DBMS - 2 ¿Es posible utilizar el nombre de la acción como clave en este caso? En general, sí, pero existe la posibilidad de que alguna empresa emita acciones diferentes y las llame únicamente por su propio nombre. En este caso ya no habrá unicidad. En la práctica, se utiliza con bastante frecuencia una clave primaria artificial. De acuerdo, utilizar un nombre completo como clave única en una tabla que contiene registros de personas no garantizará la unicidad. Además de utilizar una combinación de nombre completo y fecha de nacimiento.

Tipos de datos en DBMS

Como cualquier otro lenguaje de programación, SQL tiene tipificación de datos. Estos son los tipos de datos SQL más comunes: Tipos enteros
tipo SQL Sinónimos de SQL Coincidencia en Java Descripción
EN T INT4,ENTERO java.lang.Integer Entero de 4 bytes, -2147483648 … 2147483647
BOOLEANO BOOL, POCO java.lang.booleano Verdadero Falso
PEQUEÑO java.lang.Byte Entero de 1 byte, -128 … 127
PEQUEÑO INT2 java.lang.corto Entero de 2 bytes, -32768 … 32767
EMPEZANDO INT8 java.lang.largo Entero de 8 bytes, -9223372036854775808… 9223372036854775807
AUTOINCREMENTO INCREMENTO java.lang.largo Un contador incremental exclusivo de la tabla. Si se inserta un nuevo valor en él, se incrementa en 1. Los valores generados nunca se repiten.
Real
tipo SQL Sinónimos de SQL Coincidencia en Java Descripción
DECIMALES(N,M) DICIEMBRE, NÚMERO java.math.BigDecimal Decimal de precisión fija (N dígitos enteros y M dígitos fraccionarios). Diseñado principalmente para trabajar con datos financieros.
DOBLE FLOTADOR8 java.lang.Double Número real de doble precisión (8 bytes).
REAL FLOTADOR4 java.lang.Real Número real de precisión simple (4 bytes).
Cadena
tipo SQL Sinónimos de SQL Coincidencia en Java Descripción
VARCHAR(N) NVARCHAR java.lang.String Cadena UNICODE de longitud N. Longitud limitada a 2147483647 Carga todo el contenido de la cadena en la memoria.
fecha y hora
tipo SQL Sinónimos de SQL Coincidencia en Java Descripción
TIEMPO java.time.LocalTime, java.sql.Time Tiempo de almacenamiento (hasta nanosegundos), al convertir a DATETIME, la fecha se establece en el 1 de enero de 1970.
FECHA java.time.LocalDate, java.sql.Timestamp Almacenamiento de fechas en formato aaaa-mm-dd, la hora se establece en 00:00
FECHA Y HORA MARCA DE TIEMPO java.time.LocalDateTime, java.sql.Timestamp Almacenamiento de fecha + hora (sin tener en cuenta zonas horarias).
Almacenamiento de grandes volúmenes de datos.
tipo SQL Coincidencia en Java Descripción
GOTA java.io.InputStream, java.sql.Blob Almacenamiento de datos binarios (imágenes, archivos...).
CLOB java.io.Reader, java.sql.Clob El almacenamiento de datos de texto de gran tamaño (libros, artículos...), a diferencia de VARCHAR, carga los datos en la memoria en porciones.

estilo de escritura SQL

Para muchos idiomas, existen pautas de formato de código. Normalmente, estos documentos contienen reglas para nombrar variables, constantes, métodos y otras estructuras del lenguaje. Entonces, para Python existe PEP8, para Java: convenciones de código Oracle para Java . Se han creado varios conjuntos diferentes para SQL, que son ligeramente diferentes entre sí. De todos modos, debes desarrollar el hábito de seguir reglas al formatear tu código, especialmente si trabajas en equipo. Las reglas podrían ser, por ejemplo, las siguientes (por supuesto, usted mismo puede desarrollar un conjunto diferente de reglas, lo principal es cumplirlas en el futuro):
  • Las palabras clave y reservadas, incluidos comandos y operadores, deben escribirse en mayúsculas: CREATE TABLE, CONSTRAINT...
  • Los nombres de tablas, campos y otros objetos no deben coincidir con las palabras clave del lenguaje SQL (consulte el enlace al final del artículo), pero pueden contenerlas.
  • Los nombres de las tablas deben reflejar su propósito. Están escritos en letras minúsculas. Las palabras del nombre están separadas entre sí por guiones bajos. La palabra al final debe estar en plural : traders (comerciantes), share_rates (tasa de acciones).
  • Los nombres de los campos de la tabla deben reflejar su propósito. Deben estar escritos en letras minúsculas, las palabras del nombre deben tener el formato Camel Case y la palabra al final debe usarse en singular : nombre (nombre), share_rates (tasa de participación).
  • Los campos de clave artificial deben contener la palabra id.
  • Los nombres de CONSTRAINT deben seguir las convenciones de nomenclatura de tablas. También deben incluir los campos y tablas involucrados en ellos, comenzar con un prefijo semántico: check_ (comprobar el valor del campo), pk_ (clave primaria), fk_ (clave externa), uniq_ (uniq_ del campo), idx_ (índice). Ejemplo: pk_traider_share_actions_id (clave principal en el campo de identificación de la tabla trader_share_actions).
  • Y así sucesivamente, a medida que estudie SQL, la lista de reglas se irá reponiendo/cambiando.

diseño de SGBD

Inmediatamente antes de crear un DBMS, es necesario diseñarlo. El esquema final contiene tablas, un conjunto de campos, CONSTRAINT, claves, condiciones predeterminadas para los campos, relaciones entre tablas y otras entidades de la base de datos. En Internet puede encontrar muchos diseñadores gratuitos en línea y fuera de línea para diseñar DBMS pequeños. Intente escribir algo como "Diseñador de bases de datos gratis" en un motor de búsqueda. Estas aplicaciones tienen propiedades adicionales útiles:
  • Puede generar comandos SQL para crear un DBMS.
  • Muestre visualmente la configuración en el diagrama.
  • Le permite mover tablas para una mejor visualización.
  • Muestre claves, índices, relaciones, valores predeterminados y similares en el diagrama.
  • Pueden almacenar de forma remota el esquema DBMS.
Por ejemplo, dbdiffo.com resalta claves, muestra campos no vacíos y contadores AI (AutoIncrement) con la etiqueta NN:
Parte 2. Estructura, tablas y tipos de datos del DBMS - 3

Crear tablas en un DBMS

Entonces tenemos un diagrama. Ahora pasemos a la creación de tablas (CREAR TABLA). Para ello es recomendable que dispongamos de datos preliminares:
  • nombre de la tabla
  • nombres y tipos de campos
  • restricciones (RESTRICCIONES) en los campos
  • valores predeterminados para los campos (si están disponibles)
  • clave primaria (CLAVE PRIMARIA) si está disponible
  • conexiones entre tablas (CLAVE EXTRANJERA)
No estudiaremos en detalle todas las opciones del comando CREATE TABLE, veremos los conceptos básicos de SQL usando el ejemplo de creación de una tabla para traders:
CREATE TABLE traiders(
	id BIGINT AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(255) NOT NULL,
	freqTiсk INTEGER NOT NULL,
	cash  DECIMAL(15,2) NOT NULL DEFAULT 1000,
	tradingMethod INTEGER NOT NULL,
	changeProbability INTEGER NOT NULL DEFAULT 50,
	about VARCHAR(255) NULL
);
ALTER TABLE traiders ADD CONSTRAINT check_traiders_tradingMethod
	CHECK(tradingMethod IN (1,2,3));
ALTER TABLE traiders ADD CONSTRAINT check_traiders_changeProbability
	CHECK(changeProbability <= 100 AND changeProbability > 0)
Miremos más de cerca:
  • CREATE TABLE traiders(descripción del campo): crea una tabla con el nombre especificado; en la descripción, los campos están separados por una coma. Cualquier comando termina con punto y coma.
  • La descripción del campo comienza con su nombre, seguido de su tipo, CONSTRAINT y valor predeterminado.
  • id BIGINT AUTO_INCREMENT PRIMARY KEY– el campo id de tipo entero es una clave primaria y un contador incremental (por cada nuevo registro para el campo id, se generará un valor mayor en uno al creado previamente para esta tabla).
  • cash DECIMAL(15,2) NOT NULL DEFAULT 1000– campo de efectivo, decimal, 15 dígitos antes del punto decimal y dos después (datos financieros, por ejemplo, dólares y centavos). No se pueden aceptar valores NULL. Si no se proporciona ningún valor, obtendrá el valor 1000.
  • about VARCHAR(255) NULL– el campo Acerca de, una cadena de hasta 255 caracteres, puede aceptar valores vacíos.
Tenga en cuenta que podemos establecer parte de las condiciones CONSTRAINT después de crear la tabla. Consideremos la construcción para modificar la estructura de la tabla y sus campos: ALTER TABLE nombre_tabla ADD CONSTRAINT nombre_restricción VERIFICAR (condición) usando ejemplos:
  • CHECK(tradingMethod IN (1,2,3))– el campo tradingMethod solo puede tomar valores 1,2,3
  • CHECK(changeProbability <= 100 AND changeProbability > 0)– el campo changeProbability puede tomar valores enteros en el rango de 1 a 100

Relaciones entre tablas

Para analizar la descripción de las relaciones entre tablas, veamos la creación de share_rates:
CREATE TABLE share_rates(
	id BIGINT AUTO_INCREMENT PRIMARY KEY,
	operDate datetime NOT NULL,
	share BIGINT NOT NULL,
	rate DECIMAL(15,2) NOT NULL
);
ALTER TABLE share_rates ADD FOREIGN KEY (share) REFERENCES shares(id)
Parte 2. Estructura, tablas y tipos de datos del DBMS - 4
Una referencia a los valores de otra tabla se puede establecer de la siguiente manera: ALTER TABLEtable_from_what_referred ADD FOREIGN KEY(field_that_referred) REFERENCEStable_to_what_referred (field_that_referred to) Dejemos que en acciones tenemos registros sobre acciones, por ejemplo, para id=50 almacenamos acciones de Microsoft con un precio inicial de 17,5, un delta de 20 y una probabilidad de cambio del 4%. Para la tabla share_rates obtenemos tres propiedades principales:
  • Solo necesitamos almacenar en el campo compartido solo el valor de la clave de identificación de la tabla de acciones para poder usarlo para obtener la información restante (nombre, etc.) de la tabla de acciones.
  • No podemos crear una tarifa para una promoción inexistente. No puede insertar un valor inexistente en el campo compartir (para el cual no hay ningún registro en la tabla de acciones con esta identificación), ya que no habrá correspondencia entre las tablas.
  • No podemos eliminar una entrada de acciones para las cuales las tasas se establecen en share_rates.
Los dos últimos puntos sirven para garantizar la integridad de los datos almacenados. Puedes ver la creación de tablas SQL de nuestra emulación y ejemplos de consultas SQL en la implementación Java de métodos de las clases correspondientes usando el enlace al repositorio de github al final del artículo. la tercera parte
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION