{"id":289,"date":"2023-09-03T16:22:19","date_gmt":"2023-09-03T14:22:19","guid":{"rendered":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/?page_id=289"},"modified":"2025-03-09T14:33:03","modified_gmt":"2025-03-09T12:33:03","slug":"1-5-creacion-de-tablas-y-restricciones","status":"publish","type":"page","link":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/1-5-creacion-de-tablas-y-restricciones\/","title":{"rendered":"1.5. Creaci\u00f3n de tablas y restricciones"},"content":{"rendered":"<p>Una base de datos est\u00e1 formada por un conjunto de tablas que nos permitir\u00e1n estructurar la informaci\u00f3n que percibimos en un escenario concreto del mundo real. Cada tabla almacenar\u00e1 en forma de registros la serie de ejemplos de cada clase de entidades o relaciones entre entidades especificadas previamente. Para crear una tabla de registros vac\u00eda con el comando <code>CREATE TABLE<\/code> es necesario primero declarar sus atributos.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">CREATE TABLE nombre\r\n    (campo1 tipo1 [NOT NULL, AUTO_INCREMENT],\r\n    campo2 tipo2 [NOT NULL, AUTO_INCREMENT],\r\n    ...\r\n    campoN tipoN [NOT NULL, AUTO_INCREMENT],\r\n    PRIMARY KEY (campox, campoy, ...),\r\n    [FOREIGN KEY (campox, campoy, ...)\r\n    REFERENCES tabla(campoa, campob, ...)]);<\/pre>\n<p>A la hora de definir la clase de informaci\u00f3n que almacenaremos en cada atributo, MySQL proporciona una gran variedad de tipos num\u00e9ricos y alfanum\u00e9ricos b\u00e1sicos (tabla 2). El espacio de memoria requerido para almacenar cada variable depende de la precisi\u00f3n especificada en cada caso. Los tipos <code>DATE<\/code> y <code>TIME<\/code> resultan especialmente \u00fatiles para llevar el registro de nuestras actividades en el tiempo. El usuario puede declarar, adem\u00e1s, variables del tipo objeto (en ingl\u00e9s, <em>Binary Large Objects<\/em> o BLOB) para almacenar ficheros de texto, documentos en formato PDF o incluso im\u00e1genes dentro de alguna tabla de la base de datos.<\/p>\n<div class=\"tabletitle\"><p>Tabla 2. Tipos de datos en MySQL.<\/p>\n<\/div>\n<table width=\"555\">\n<tbody>\n<tr class=\"table-header\">\n<td width=\"140\"><strong>\u00a0Tipo gen\u00e9rico<\/strong><\/td>\n<td width=\"415\"><strong>\u00a0Tipos MySQL<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"140\">\u00a0Entero<\/td>\n<td width=\"415\"><code>TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT<\/code><\/td>\n<\/tr>\n<tr>\n<td width=\"140\">\u00a0Decimal<\/td>\n<td width=\"415\"><code>DECIMAL, FLOAT, DOUBLE\/REAL<\/code><\/td>\n<\/tr>\n<tr>\n<td width=\"140\">\u00a0Texto<\/td>\n<td width=\"415\"><code>CHAR, VARCHAR, TINYTEXT, TEXT<\/code><\/td>\n<\/tr>\n<tr>\n<td width=\"140\">\u00a0Objetos<\/td>\n<td width=\"415\"><code>BLOB, MEDIUMBLOB, LONGBLOB<\/code><\/td>\n<\/tr>\n<tr>\n<td width=\"140\">\u00a0Tiempo<\/td>\n<td width=\"415\"><code>DATE, TIME<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"tablefooter\"><p>Fuente: elaboraci\u00f3n propia.<\/p>\n<\/div>\n<p>Junto con la declaraci\u00f3n de los atributos, para crear una tabla debemos especificar qu\u00e9 atributo o combinaci\u00f3n de atributos ser\u00e1 la clave primaria, identificando de forma un\u00edvoca cada instancia. En caso de existir, las claves for\u00e1neas para referenciar a los atributos de otras tablas tambi\u00e9n deben indicarse expl\u00edcitamente.<\/p>\n<p>El dise\u00f1ador puede activar dos controles internos sobre el valor de un atributo en el momento de registrar nuevas instancias en la base de datos. En primer lugar, es posible rechazar aquellos registros que no posean un valor definido para un atributo concreto. Esta circunstancia se especifica con la construcci\u00f3n <code>NOT NULL<\/code>, justo despu\u00e9s de la declaraci\u00f3n de tipos. <code>NOT<\/code> <code>NULL<\/code> ser\u00eda una restricci\u00f3n de campo obligatorio, no acepta valores nulos. En caso contrario, el sistema asignar\u00e1 por defecto el valor NULL a ese campo y aceptar\u00e1 valores nulos. Este requerimiento debe satisfacerse inexcusablemente en aquellos atributos que pertenecen a la clave primaria. En segundo lugar, para los identificadores num\u00e9ricos asociados a cada instancia, el propio sistema puede encargarse de gestionar un contador autom\u00e1tico de valores mediante la construcci\u00f3n <strong><code>AUTO_INCREMENT<\/code><\/strong>.<\/p>\n<p>Volviendo nuevamente a nuestra base de datos <strong>catalogo<\/strong>, nos encontramos ahora en disposici\u00f3n de crear las tablas del cat\u00e1logo de genes especificadas formalmente a continuaci\u00f3n. Debemos escoger adecuadamente los tipos de datos para cada atributo o campo, seg\u00fan su contenido, definiendo claramente cu\u00e1les son las claves primarias y for\u00e1neas. El usuario puede empezar creando las tablas m\u00e1s elementales, es decir, aquellas que no poseen claves for\u00e1neas (genomas y funciones). Observad c\u00f3mo declaramos la clave primaria y nos aseguramos de que ninguna instancia puede darse de alta en la base de datos con un valor nulo para las claves primarias, <strong>especie <\/strong>y <strong>funci\u00f3n<\/strong>. Para verificar que el proceso de creaci\u00f3n ha funcionado correctamente, el usuario puede consultar en la base de datos sobre las tablas existentes con el comando <code>SHOW TABLES<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"mowtwo\">mysql&gt; SHOW TABLES;\r\n\r\nEmpty set (0,00 sec)\r\n\r\nmysql&gt; CREATE TABLE genomas\r\n    -&gt; especie VARCHAR(100) NOT NULL,\r\n    -&gt; nombre VARCHAR(100),\r\n    -&gt; descripcion TEXT,\r\n    -&gt; PRIMARY KEY (especie));\r\n\r\nQuery OK, 0 row affected (0.28 sec)\r\n\r\nmysql&gt; CREATE TABLE funciones\r\n    -&gt; funcion VARCHAR(20) NOT NULL,\r\n    -&gt; descripcion VARCHAR(100),\r\n    -&gt; PRIMARY KEY (funcion));\r\n\r\nQuery OK, 0 row affected (0.03 sec)\r\n\r\nmysql&gt; SHOW TABLES;\r\n+--------------------+\r\n| Tables_in_catalogo |\r\n+--------------------+\r\n| funciones           |\r\n| genomas            |\r\n+--------------------+\r\n2 rows in set (0.00 sec)<\/pre>\n<p>Es posible revisar la definici\u00f3n de una tabla con la instrucci\u00f3n <strong><code>DESCRIBE<\/code><\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"mowtwo\">mysql&gt; DESCRIBE genomas;\r\n+-------------+--------------+------+-----+---------+-------+\r\n| Field       | Type         | Null | Key | Default | Extra |\r\n+-------------+--------------+------+-----+---------+-------+\r\n| especie     | varchar(100) | NO   | PRI | NULL    |       |\r\n| nombre      | varchar(100) | YES  |     | NULL    |       |\r\n| descripcion | text         | YES  |     | NULL    |       |\r\n+-------------+--------------+------+-----+---------+-------+\r\n3 rows in set (0.01 sec)<\/pre>\n<p>A continuaci\u00f3n, para crear la tabla <strong>genes<\/strong>, adem\u00e1s de la clave primaria, indicamos un campo o atributo que es la clave for\u00e1nea (que debe apuntar o hacer referencia a la clave primaria de la tabla <em>genomas<\/em>):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"mowtwo\">mysql&gt; CREATE TABLE genes\r\n    -&gt; (nombre VARCHAR(20) NOT NULL,\r\n    -&gt; cromosoma VARCHAR(5),\r\n    -&gt; hebra VARCHAR(1),\r\n    -&gt; inicio INT,\r\n    -&gt; final INT,\r\n    -&gt; proteina VARCHAR(20),\r\n    -&gt; especie VARCHAR(100),\r\n    -&gt; PRIMARY KEY (nombre),\r\n    -&gt; FOREIGN KEY (especie)\r\n    -&gt; REFERENCES genomas(especie));\r\n\r\nQuery OK, 0 rows affected (0.06 sec)\r\n\r\nmysql&gt; DESCRIBE genes;\r\n+------------+-------------+------+-----+---------+-------+\r\n| Field      | Type        | Null | Key | Default | Extra |\r\n+------------+-------------+------+-----+---------+-------+\r\n| nombre     | varchar(20) | NO   | PRI | NULL    |       |\r\n| cromosoma  | varchar(5)  | YES  |     | NULL    |       |\r\n| hebra      | varchar(1)  | YES  |     | NULL    |       |\r\n| inicio     | int(11)     | YES  |     | NULL    |       |\r\n| final      | int(11)     | YES  |     | NULL    |       |\r\n| proteina   | varchar(20) | YES  |     | NULL    |       |\r\n| especie    | varchar(100)| YES  | MUL | NULL    |       |\r\n+------------+-------------+------+-----+---------+-------+\r\n7 rows in set (0.00 sec)<\/pre>\n<p>Finalmente, creamos la tabla <strong>anotaciones <\/strong>para relacionar los genes con las anotaciones funcionales. Junto con los dos valores que identifican cada registro (<strong>gen<\/strong> y <strong>funci<\/strong><strong>on<\/strong>), a\u00f1adiremos un atributo para registrar el origen de la informaci\u00f3n:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"mowtwo\">mysql&gt; CREATE TABLE anotaciones\r\n    -&gt; (nombre VARCHAR(20) NOT NULL,\r\n    -&gt; funcion VARCHAR(20) NOT NULL,\r\n    -&gt; origen VARCHAR(20),\r\n    -&gt; PRIMARY KEY (nombre, funcion),\r\n    -&gt; FOREIGN KEY (nombre)\r\n    -&gt; REFERENCES genes(nombre),\r\n    -&gt; FOREIGN KEY (funcion)\r\n    -&gt; REFERENCES funciones(funcion));\r\n\r\nQuery OK, rows affected (0.11 sec)\r\n\r\nmysql&gt; DESCRIBE anotaciones;\r\n+---------+--------------+------+-----+---------+-------+\r\n| Field   | Type         | Null | Key | Default | Extra |\r\n+---------+--------------+------+-----+---------+-------+\r\n| nombre  | varchar(20)  | NO   | PRI | NULL    |       |\r\n| funcion | varchar(20)  | NO   | PRI | NULL    |       |\r\n| origen  | varchar(20)  | YES  |     | NULL    |       |\r\n+---------+--------------+------+-----+---------+-------+\r\n3 rows in set (0.01 sec)<\/pre>\n<p>Es posible definir otras restricciones a los campos de las tablas con el comando <code>CHECK<\/code>.<\/p>\n<p>Por ejemplo, podemos indicar que un campo num\u00e9rico como el campo <strong>incio <\/strong>de la tabla <strong>genes <\/strong>que es tipo num\u00e9rico solo acepte valores positivos <code>CHECK (inicio &gt;0)<\/code>, o que un campo de tipo cadena de caracteres solo acepte determinados valores; por ejemplo, para que el campo <em>hebra<\/em> de la tabla <em>genes <\/em>solo acepte los caracteres \u00ab+\u00bb o \u00ab-\u00bb, podemos hacer <code>hebra ENUM<\/code>(&#8216;<code>+<\/code>&#8216;,&#8217;<code>-<\/code>&#8216;).<\/p>\n<p>Una vez creada la tabla podemos modificarla con la instrucci\u00f3n <strong>ALTER TABLE<\/strong>.<\/p>\n<p>Por ejemplo, si queremos eliminar el campo origen de la tabla <strong>anotaciones <\/strong>escribimos<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">ALTER TABLE anotaciones DROP COLUMN origen;<\/pre>\n<p>y si queremos volver a a\u00f1adir el mismo campo escribimos<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">ALTER TABLE anotaciones ADD origen VARCHAR(20);<\/pre>\n<p>Durante el tiempo de vida de una base de datos es frecuente que debamos actualizar su contenido. En determinados casos, esto puede implicar la eliminaci\u00f3n completa de usuarios, de tablas o incluso, de la propia base de datos. Para implementar estos servicios, MySQL posee la familia de comandos <code>DROP<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"droide\">DROP DATABASE basededatos;\r\nDROP USER usuario;\r\nDROP TABLE tabla;<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Una base de datos est\u00e1 formada por un conjunto de tablas que nos permitir\u00e1n estructurar la informaci\u00f3n que percibimos en un escenario concreto del mundo real. Cada tabla almacenar\u00e1 en forma de registros la serie de ejemplos de cada clase de entidades o relaciones entre entidades especificadas previamente. Para crear una tabla de registros vac\u00eda [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"acf":[],"_links":{"self":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/pages\/289"}],"collection":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/comments?post=289"}],"version-history":[{"count":11,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/pages\/289\/revisions"}],"predecessor-version":[{"id":1005,"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/pages\/289\/revisions\/1005"}],"wp:attachment":[{"href":"http:\/\/eines-informatiques.recursos.uoc.edu\/gestion-de-datos\/es\/wp-json\/wp\/v2\/media?parent=289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}