Pregunta

Me preguntaba la opinión de la gente sobre el nombre de las columnas de ID en las tablas de la base de datos.

Si tengo una tabla llamada Facturas con una clave principal de una columna de identidad, llamaría a esa columna ID de factura para que no entren en conflicto con otras tablas y es obvio lo que es.

Donde estoy trabajando, han llamado a todas las columnas de ID ID.

Entonces ellos harían lo siguiente:

Select  
    i.ID 
,   il.ID 
From
    Invoices i
    Left Join InvoiceLines il
        on i.ID = il.InvoiceID

Ahora, veo algunos problemas aquí:
1. Necesitaría un alias de las columnas en la selección de
2. ID = InvoiceID no cabe en mi cerebro
3. Si no hizo un alias de las tablas y se refirió a InvoiceID, ¿es obvio en qué tabla está?

¿Qué opinan los demás sobre el tema?

¿Fue útil?

Solución

ID es un antipattern de SQL. Consulte http: // www.amazon.com/s/ref=nb_sb_ss_i_1_5?url=search-alias%3Dstripbooks&field-keywords=sql+antipatterns&sprefix=sql+a

Si tiene muchas tablas con ID como el ID, lo que hace que la presentación de informes sea mucho más difícil. Oscurece el significado y hace que las consultas complejas sean más difíciles de leer, además de requerir que utilice alias para diferenciarse en el informe.

Además, si alguien es lo suficientemente tonto como para utilizar una combinación natural en una base de datos donde está disponible, se unirá a los registros incorrectos.

Si desea usar la sintaxis de USO que permiten algunos dbs, no puede hacerlo si usa ID.

Si usa ID, puede terminar fácilmente con una combinación errónea si está copiando la sintaxis de la combinación (¡no me diga que nadie hace esto!) y olvide cambiar el alias en la condición de combinación.

Así que ahora tienes

select t1.field1, t2.field2, t3.field3
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t1.id = t3.table2id

cuando quisiste decir

select t1.field1, t2.field2, t3.field3 
from table1 t1 
join table2 t2 on t1.id = t2.table1id
join table3 t3 on t2.id = t3.table2id

Si usa tablenameID como el campo id, este tipo de error accidental es mucho menos probable que ocurra y mucho más fácil de encontrar.

Otros consejos

Siempre preferí ID a TableName + ID para la columna de ID y luego TableName + ID para una clave externa. De esa manera, todas las tablas tienen el mismo nombre para el campo de identificación y no hay una descripción redundante. Esto me parece más sencillo porque todas las tablas tienen el mismo nombre de campo de clave principal.

En cuanto a unir tablas y no saber qué campo de Id pertenece a qué tabla, en mi opinión, la consulta debe escribirse para manejar esta situación. Donde trabajo, siempre preferimos los campos que usamos en una declaración con el alias de tabla / tabla.

Ha habido una pelea de nerd por esto en mi compañía últimamente. El advenimiento de LINQ ha hecho que el patrón redundante de tablename + ID sea aún más obvio a mis ojos. Creo que la mayoría de las personas razonables dirán que si escribe su SQL de forma que tenga que especificar nombres de tablas para diferenciar FKs , entonces no solo ahorra en escribir, sino que agrega claridad a su SQL para usar solo el ID, ya que puede ver claramente cuál es el PK y cuál es el FK .

Por ejemplo,

DE los empleados e     LEFT JOIN Customers c ON e.ID = c.EmployeeID

no solo me dice que los dos están vinculados, sino que es PK y que es FK . Mientras que en el estilo antiguo, estás obligado a mirar o esperar que hayan sido bien nombrados.

Utilizamos InvoiceID , no ID . Hace que las consultas sean más legibles: cuando solo ve ID puede significar cualquier cosa, especialmente cuando crea un alias en la tabla con i .

Estoy de acuerdo con Keven y algunas otras personas aquí en que la PK para una tabla debería ser simplemente Id. y las claves foráneas listan la Id. de Otra Tabla +.

Sin embargo, deseo agregar una razón que recientemente le dio más peso a este argumento.

En mi posición actual estamos empleando el marco de la entidad mediante la generación de POCO. Usando la convención de nomenclatura estándar de Id, el PK permite la herencia de una clase base de poco con validación y tal para las tablas que comparten un conjunto de nombres de columnas comunes. El uso de Tablename + Id como PK para cada una de estas tablas destruye la capacidad de usar una clase base para estas.

Sólo un poco de alimento para el pensamiento.

No es realmente importante, es probable que tengas problemas similares en todas las convenciones de nombres.

Pero es importante ser coherente para que no tenga que mirar las definiciones de la tabla cada vez que escribe una consulta.

Mi preferencia es también ID para clave principal y TableNameID para clave externa. También me gusta tener una columna " nombre " en la mayoría de las tablas donde tengo el identificador legible por el usuario (es decir, nombre :-)) de la entrada. Esta estructura ofrece una gran flexibilidad en la aplicación en sí misma, puedo manejar tablas en masa de la misma manera. Esto es algo muy poderoso. Por lo general, un software OO se construye sobre la base de datos, pero el conjunto de herramientas OO no se puede aplicar porque la propia db no lo permite. Tener el id y el nombre de las columnas todavía no es muy bueno, pero es un paso.

  

Seleccionar
      i.ID, il.ID De       Facturas i       Left Join InvoiceLines il           en i.ID = il.InvoiceID

¿Por qué no puedo hacer esto?

Select  
    Invoices.ID 
,   InvoiceLines.ID 
From
    Invoices
    Left Join InvoiceLines
        on Invoices.ID = InvoiceLines.InvoiceID

En mi opinión, esto es muy fácil de leer y simple. Nombrar variables como i y il es una mala elección en general.

Acabo de empezar a trabajar en un lugar que usa solo " ID " (en las tablas principales, a las que hace referencia TableNameID en claves externas), y ya han encontrado DOS problemas de producción causados ??directamente por ella.

En un caso, la consulta usó " ... donde ID en (SELECCIONAR ID DE Otra Tabla ... " en lugar de " ... donde ID en (SELECCIONAR IDENTIFICACIÓN DE Otra Tabla ... ".

Honestamente, ¿alguien puede decir que no habría sido mucho más fácil de detectar si se usaran nombres completos y coherentes donde se hubiera leído la declaración incorrecta " ... donde estaba TransID (SELECCIONE OtherTableID from OtherTable ... " ;? No lo creo.

El otro problema ocurre cuando se refactoriza el código. Si usa una tabla temporal, mientras que anteriormente la consulta se salía de una tabla principal, entonces el código antiguo dice " ... dbo.MyFunction (t.ID) ... " y si eso no se cambia pero " t " ahora se refiere a una tabla temporal en lugar de la tabla principal, ni siquiera recibe un error, solo resultados erróneos.

Si generar errores innecesarios es un objetivo (¿tal vez algunas personas no tienen suficiente trabajo?), este tipo de convención de nombres es excelente. De lo contrario, una forma de nombrar de manera consistente es el camino a seguir.

En aras de la simplicidad, la mayoría de las personas nombran la columna en el ID de la tabla. Si tiene una referencia de clave externa en otra tabla, entonces explícitamente la llaman InvoiceID (para usar su ejemplo) en el caso de uniones, usted está aliasando la tabla de todos modos, por lo que el inv.ID explícito es aún más simple que inv.IDvoDial

Desde este punto de vista, desde la perspectiva de un diccionario de datos formal, denominaría el elemento de datos invoice_ID . En general, el nombre de un elemento de datos será único en el diccionario de datos e idealmente tendrá el mismo nombre en todas partes, aunque a veces se pueden requerir términos adicionales de calificación según el contexto, por ejemplo. el elemento de datos denominado employee_ID se podría usar dos veces en el organigrama y, por lo tanto, se califica como supervisor_employee_ID y subordinate_employee_ID respectivamente.

Obviamente, las convenciones de nombres son subjetivas y son una cuestión de estilo. Considero que las directrices ISO / IEC 11179 son un punto de partida útil.

Para el DBMS, veo las tablas como colecciones de entidades (excepto aquellas que solo contienen una fila, por ejemplo, tabla de cofig, tabla de constantes, etc.), por ejemplo. la tabla donde mi employee_ID es la clave se llamaría Personal . Así que enseguida la convención TableNameID no funciona para mí.

He visto el estilo TableName.ID = PK TableNameID = FK usado en grandes modelos de datos y tengo que decir que me parece un poco confuso: prefiero que el nombre de un identificador sea el mismo en todo no cambia el nombre en función de la tabla en la que aparece. Algo que debe tenerse en cuenta es que el estilo mencionado anteriormente se usa en las tiendas que agregan una columna IDENTITY (incremento automático) a cada en la tabla mientras se evitan las claves naturales y compuestas en claves externas. Esas tiendas tienden a no tener diccionarios de datos formales ni construir a partir de modelos de datos. Nuevamente, esto es simplemente una cuestión de estilo y una a la que no me suscribo personalmente. Así que en última instancia, no es para mí.

Dicho todo esto, puedo ver un caso en el que a veces se elimina el calificador del nombre de la columna cuando el nombre de la tabla proporciona un contexto para hacerlo, por ejemplo. el elemento denominado employee_last_name puede convertirse simplemente en last_name en la tabla Personnel . El fundamento aquí es que el dominio es 'apellidos de personas' y es más probable que sea UNION ed con last_name columnas de otras tablas en lugar de se usará como una clave foránea en en otra tabla, pero nuevamente ... tal vez solo cambie de opinión, a veces nunca se puede decir. Esa es la cosa: el modelado de datos es parte de arte, parte de ciencia.

Yo personalmente prefiero (como se ha indicado anteriormente) Table.ID para PK y TableID para el FK . Incluso (por favor, no me dispares), Microsoft Access recomienda esto.

SIN EMBARGO, TAMBIÉN sé que algunas herramientas de generación prefieren el TableID para PK porque tienden a vincular todos los nombres de columnas que contienen 'ID' en la palabra, ¡INCLUYENDO ID! !!

Incluso el diseñador de consultas hace esto en Microsoft SQL Server (y para cada consulta que crees, terminas eliminando todas las relaciones innecesarias que se crearon en todas las tablas en la columna ID)

ASÍ, por más que mi TOC interno lo odie, comparto con la convención TableID . Recordemos que se llama Data BASE , ya que será la base para, con suerte, muchas muchas aplicaciones futuras. Y todas las tecnologías deberían beneficiarse de un esquema bien normalizado con una descripción clara.

No hace falta decir que sí trazo mi línea cuando la gente comienza a usar TableName, TableDescription y demás. En mi opinión, las convenciones deberían hacer lo siguiente:

  • Nombre de la tabla: Pluralizado. Ex. Empleados
  • Alias ??de tabla: Nombre completo de la tabla, en singularizado. Ej.

    SELECT Employee.*, eMail.Address
    FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
    

[Update?

Además, hay algunas publicaciones válidas en este hilo sobre columnas duplicadas debido al " tipo de relación " o rol Por ejemplo, si una tienda tiene un EmployeeID , eso me dice que me agacho. Así que a veces hago algo como Store.EmployeeID_Manager . Claro que es un poco más grande, pero al menos la gente no se volverá loca tratando de encontrar table ManagerID , o lo que EmployeeID está haciendo allí. Cuando la consulta es DONDE lo simplificaría como:     SELECCIONE EmployeeID_Manager como ManagerID DE la tienda

Creo que puedes usar cualquier cosa para la " ID " siempre y cuando seas consistente. Es importante incluir el nombre de la tabla. Yo sugeriría usar una herramienta de modelado como Erwin para hacer cumplir los convenios y estándares de nomenclatura, de modo que al escribir consultas es fácil entender las relaciones que pueden existir entre las tablas.

Lo que quiero decir con la primera declaración es que, en lugar de ID, puedes usar otra cosa como 'recno'. Entonces, esta tabla tendría un PK de invoice_recno y así sucesivamente.

Saludos, Ben

Mi voto es para InvoiceID para el ID de la tabla. También utilizo la misma convención de nomenclatura cuando se usa como clave externa y uso nombres de alias inteligentes en las consultas.

 Select Invoice.InvoiceID, Lines.InvoiceLine, Customer.OrgName
 From Invoices Invoice
 Join InvoiceLines Lines on Lines.InvoiceID = Invoice.InvoiceID
 Join Customers Customer on Customer.CustomerID = Invoice.CustomerID

Claro, es más largo que algunos otros ejemplos. Pero sonrie Esto es para la posteridad y algún día, algún pobre programador junior tendrá que alterar tu obra maestra. En este ejemplo, no hay ambigüedad y, a medida que se agregan tablas adicionales a la consulta, agradecerás la verbosidad.

Para el nombre de la columna en la base de datos, usaría " ID de factura " ;.

Si copio los campos en una estructura sin nombre a través de LINQ, puedo nombrarlo " ID " allí, si es el único ID en la estructura.

Si la columna NO se va a utilizar en una clave externa, de modo que solo se use para identificar de forma única una fila para editarla o eliminarla, la nombraré " PK " ;.

Si le das a cada clave un nombre único, por ejemplo, " invoices.invoice_id " en lugar de " invoices.id " ;, entonces puede usar la " combinación natural " y " utilizando " Operadores sin preocupaciones. Por ejemplo,

SELECT * FROM invoices NATURAL JOIN invoice_lines
SELECT * FROM invoices JOIN invoice_lines USING (invoice_id)

en lugar de

SELECT * from invoices JOIN invoice_lines
    ON invoices.id = invoice_lines.invoice_id

SQL es suficientemente detallado sin hacerlo más detallado.

Lo que hago para mantener las cosas coherentes para mí mismo (donde una tabla tiene una clave primaria de una sola columna utilizada como ID) es nombrar la clave principal de la tabla Table_pk . En cualquier lugar donde tengo una clave externa que apunta a esa clave principal de las tablas, llamo a la columna PrimaryKeyTable_fk . De esa manera, sé que si tengo un Customer_pk en mi tabla de Clientes y un Customer_fk en mi tabla de Pedidos, sé que la tabla de Pedidos se refiere a una entrada en el Cliente tabla.

Para mí, esto tiene sentido especialmente para las uniones donde creo que se lee más fácilmente.

SELECT * 
FROM Customer AS c
    INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk

FWIW, nuestro nuevo estándar (que cambia, uh, quiero decir "evoluciona" con cada nuevo proyecto) es:

  • Nombres de campo de la base de datos en minúsculas
  • Nombres de tablas en mayúsculas
  • Use los guiones bajos para separar las palabras en el nombre del campo, conviértalos al código de caso de Pascal.
  • prefijo pk_ significa clave principal
  • El sufijo
  • _id significa un número entero, ID de incremento automático
  • El prefijo
  • fk_ significa clave externa (no es necesario un sufijo)
  • sufijo _VW para las vistas
  • is_ prefijo para booleanos

Entonces, una tabla llamada NAMES podría tener los campos pk_name_id, first_name, last_name, is_alive, y fk_company y una vista llamada LIVING_CUSTOMERS_VW , definido como:

SELECT first_name, last_name
FROM CONTACT.NAMES
WHERE (is_alive = 'True')

Como han dicho otros, sin embargo, casi cualquier esquema funcionará siempre que sea consistente y no ofusque innecesariamente sus significados.

Definitivamente estoy de acuerdo con incluir el nombre de la tabla en el nombre del campo de ID, exactamente por las razones que da. En general, este es el único campo donde incluiría el nombre de la tabla.

Odio el nombre de identificación simple. Yo prefiero usar siempre la factura_id o una variante de la misma. Siempre sé qué tabla es la tabla autorizada para el ID cuando lo necesito, pero esto me confunde

SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceID = inv.ID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceLineID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.ID = inv.InvoiceID 
SELECT * from Invoice inv, InvoiceLine inv_l where 
inv_l.InvoiceLineID = inv.ID 

Lo peor de todo es la mezcla que mencionas, totalmente confusa. Tuve que trabajar con una base de datos donde casi siempre estaba foo_id, excepto en una de las identificaciones más utilizadas. Eso fue un infierno total.

Prefiero DomainName || 'CARNÉ DE IDENTIDAD'. (es decir, nombre de dominio + ID)

DomainName es a menudo, pero no siempre, el mismo que TableName.

El problema con la identificación por sí solo es que no se amplía. Una vez que tenga alrededor de 200 tablas, cada una con una primera columna llamada ID, los datos comenzarán a parecerse a todos. Si siempre calificas la ID con el nombre de la tabla, eso ayuda un poco, pero no tanto.

DomainName & amp; ID se puede utilizar para nombrar claves externas, así como claves primarias. Cuando las claves externas se nombran después de la columna a la que hacen referencia, puede ser de ayuda mnemotécnica. Formalmente, no es necesario vincular el nombre de una clave foránea a la clave a la que hace referencia, ya que la restricción de integridad referencial establecerá la referencia. Pero es muy útil cuando se trata de leer consultas y actualizaciones.

Ocasionalmente, DomainName || 'ID' no se puede usar, porque habría dos columnas en la misma tabla con el mismo nombre. Ejemplo: Employees.EmployeeID y Employees.SupervisorID. En esos casos, uso RoleName || 'ID', como en el ejemplo.

Por último, pero no menos importante, uso claves naturales en lugar de sintéticas cuando es posible. Hay situaciones en las que las claves naturales no están disponibles o no son confiables, pero hay muchas situaciones en las que la clave natural es la elección correcta. En esos casos, dejo que la clave natural tome el nombre que naturalmente tendría. Este nombre a menudo ni siquiera tiene las letras "ID" en él. Ejemplo: OrderNo donde No es una abreviatura de " Número " ;.

Para cada tabla, elijo una abreviatura de letra de árbol (por ejemplo, Empleados = > Emp)

De esa manera, una clave principal numérica y autonumérica se convierte en nkEmp .

Es breve, único en toda la base de datos y conozco exactamente sus propiedades de un vistazo.

Mantengo los mismos nombres en SQL y en todos los lenguajes que uso (principalmente C #, Javascript, VB6).

Consulte el sitio de Interakt en convenciones de denominación para un sistema bien pensado de nombres de tablas y columnas. El método utiliza un sufijo para cada tabla ( _prd para una tabla de productos, o _ctg para una tabla de categorías) y lo agrega a cada columna de una tabla dada. Por lo tanto, la columna de identidad para la tabla de productos sería id_prd y, por lo tanto, es única en la base de datos.

Avanzan un paso más para comprender mejor las claves externas: la clave externa en la tabla del producto que hace referencia a la tabla de categorías sería idctg_prd , de modo que sea obvio a qué tabla pertenece ( _prd sufijo) y a qué tabla se refiere (categoría).

Las ventajas son que no hay ambigüedad con las columnas de identidad en diferentes tablas, y que puede decir de un vistazo a qué columnas se refiere una consulta por los nombres de las columnas.

Podría usar la siguiente convención de nomenclatura. Tiene sus defectos, pero resuelve sus problemas particulares.

  1. Use apodos cortos (3-4 caracteres) para los nombres de las tablas, es decir, Factura - inv , InvoiceLines - invl
  2. Nombre las columnas en la tabla usando esos apodos, es decir, inv_id , invl_id
  3. Para las columnas de referencia, use invl_inv_id para los nombres.

de esta manera se podría decir

SELECT * FROM Invoice LEFT JOIN InvoiceLines ON inv_id = invl_inv_id
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top