Los estándares SQL92 y SQL99 definen construcciones DDL . No todas las bases de datos lo admiten o tienen un nombre diferente (SQL Server tiene tipos definidos por el usuario , por ejemplo).CREATE DOMAIN
Estos permiten definir un tipo de datos restringido para ser utilizado en su base de datos, para simplificar y aplicar reglas relativas a los valores permitidos. Tal tipo de datos podría usarse en declaraciones de columna, en entradas y salidas a procedimientos y funciones almacenados, etc.
Me gustaría saber:
- ¿Las personas realmente usan dominios en sus diseños de bases de datos?
- ¿Si es así, en qué medida?
- ¿Cuán útiles son?
- ¿Qué escollos has encontrado?
Estoy tratando de evaluar la viabilidad de usarlos en el futuro desarrollo de bases de datos.
sql
sql-domain
Oded
fuente
fuente
Respuestas:
Como siempre...
Depende
¿Tiene una entidad de dominio utilizada en más de un lugar que soportar de forma nativa requeriría un esfuerzo considerable y / o restricciones y comportamientos redundantes ?
Si es así, dominio fuera. Si no, no te molestes.
He encontrado necesario crear un tipo definido por el usuario en SQL Server exactamente una vez, basado en la heurística anterior. Ya ni siquiera recuerdo qué era, pero ahorró más trabajo del que causó.
fuente
Como usuario de SQL Server y C #, no he usado tipos definidos por el usuario en la base de datos, ya que soy bastante más poderoso en el lado de la aplicación. Evento después de ORM como LINQ to SQL y Entity Framework, mi uso de las capacidades del servidor se ha reducido mucho.
Por ejemplo, estaba usando la integración CLR para cargar algunas funciones de conversión de DateTime a SQL Server para transferir fechas y horas gregorianas a otros formatos, basados en el poder de globalización de .NET. Pero ahora, las cosas son diferentes, y ya no hago eso. Simplemente cargo los datos y hago la transformación, directamente en mi capa de aplicación.
Entonces, después de casi 4 años de programación e inspección de todos los equipos en los que puedo pensar, no he encontrado ninguna muestra del uso de tipos definidos por el usuario. Tampoco lo he visto en acción en muchos blogs .NET.
Si bien esto no significa que las personas no usen el dominio de la base de datos , seguramente significa que al menos el uso del dominio de la base de datos no es tan común.
fuente
Ya hay una respuesta detallada sobre Stack Overflow. Principalmente estoy de acuerdo con eso, pero no con el ejemplo dado, cito:
Personalmente, me siento más cómodo configurando el
char(1)
tipo y definiendo una restricción en la columna. Cuando se viola la restricción, sé exactamente dónde buscar para encontrar lo que hice mal. También es más conocido que los tipos definidos por el usuario, por lo que la base de datos que usa solo restricciones sería más fácil de entender para un principiante.Por supuesto, solo es una opinión personal. Otras personas dirían que una
in ('M', 'F')
restricción no es autodocumentada y puede ser muy oscura para un desarrollador nuevo que descubre la base de datos.En mi opinión, use tipos definidos por el usuario para tipos más complicados y restricciones para algo básico. Además, cuando no puede encontrar fácilmente un nombre explícito para un tipo, existe la posibilidad de que una restricción se ajuste mejor.
fuente
No he usado esta función yo mismo, pero supongo que debes asegurarte de que:
Si su base de datos es utilizada por un solo sistema, puede tener sentido no usar esta función y agregar la lógica de verificación en su capa empresarial o su equivalente. Eso le dará más flexibilidad en la validación (digamos al usar expresiones regulares) y permitirá encapsular toda la lógica de validación en un solo lugar. Si su base de datos es compartida por varios sistemas, puede utilizar desencadenantes que sean adecuados para esta tarea.
No estoy seguro de si UDT le permite personalizar los mensajes de error devueltos al cliente cuando se encuentra un error de validación.
Los UDT son muy útiles si la misma regla de validación se aplica a varias columnas. En mi opinión, no veo esto como un caso muy común en aplicaciones comerciales con diseño de base de datos normalizado.
Quizás le interese comprobar "¿Cuál es el punto de los tipos definidos por el usuario [SQL Server]?" artículo de blog
fuente
Cuando dice "no todas las bases de datos admiten esto", creo que una mejor manera de decirlo es la siguiente:
Todas las bases de datos principales lo admiten, ya que son ampliamente compatibles con disparadores, funciones y otras características avanzadas.
Esto nos lleva a la conclusión de que esto es parte de SQL avanzado y tiene sentido en algún momento.
Lo menos posible, debido a la amplia cobertura requerida (considerando operadores, índices, etc.)
Una vez más, tan limitado como puede ser, si un tipo existente combinado con una pequeña lógica definida adicional (es decir, verificaciones, etc.) puede hacer el truco, ¿por qué ir tan lejos?
Un montón. Consideremos por un segundo un DBMS no tan bueno como MySQL, que elegí para este ejemplo por una razón: carece de un buen soporte para el tipo inet (dirección IP).
Ahora desea escribir una aplicación que se centre principalmente en datos IP como rangos y todo eso, y está atascado con el tipo predeterminado y su funcionalidad limitada, o bien escribirá funciones y operadores adicionales (como los que se admiten de forma nativa en postgreSQL para ejemplo) o escriba consultas mucho más complejas para cada funcionalidad que necesite.
Este es un caso en el que justificará fácilmente el tiempo dedicado a definir sus propias funciones (inet >> inet en PostgreSQL: rango contenido en el operador de rango).
En ese momento, ya ha justificado ampliar la compatibilidad con el tipo de datos, solo hay un paso más para definir un nuevo tipo de datos.
Ahora volvamos a PostgreSQL, que tiene un soporte de tipo realmente agradable pero no int sin firmar ... lo que necesita, porque está realmente preocupado por el almacenamiento / rendimiento (quién sabe ...), bueno, deberá agregarlo así como operadores, aunque, por supuesto, esto deriva principalmente de los operadores int existentes.
No juego con eso porque hasta ahora no he tenido un proyecto que requiera y justifique el tiempo requerido para esto.
Los problemas más importantes que puedo ver con eso serían reinventar la rueda, introducir errores en la capa "segura" (db), soporte de tipo incompleto que solo se dará cuenta meses después cuando su CONCAT (cast * AS varchar) falle porque no definió un elenco (newtype como varchar), etc.
Hay respuestas que hablan de "poco común", etc. Definitivamente, estas son y deberían ser poco comunes (de lo contrario significa que el dbms carece de muchos tipos importantes), pero por otro lado, uno debe recordar que un (buen) db es compatible con ACID ( a diferencia de una aplicación) y que todo lo relacionado con la coherencia se mantiene mejor allí.
Hay muchos casos en los que la lógica de negocios se maneja en la capa de software y podría hacerse en SQL, donde es más seguro. Los desarrolladores de aplicaciones tienden a sentirse más cómodos dentro de la capa de aplicación y, a menudo, evitan mejores soluciones implementadas en SQL, esto no debe considerarse como una buena práctica.
Los UDT pueden ser una buena solución para la optimización, un buen ejemplo se da en otra respuesta sobre el tipo m / f usando char (1). Si hubiera sido un UDT, podría ser un booleano (a menos que queramos ofrecer las opciones tercera y cuarta). Por supuesto, todos sabemos que esto no es realmente una optimización debido a la sobrecarga de la columna, pero existe la posibilidad.
fuente
En papel, los UDT son un gran concepto. Le permiten normalizar realmente su base de datos (por ejemplo, cuando tiene dos columnas que dependen entre sí) y también encapsular cualquier lógica relacionada con su nuevo tipo.
En la práctica, el precio que paga (hoy) es demasiado alto. Obviamente, está la sobrecarga del desarrollo, pero aparte de eso, pierde el soporte de una variedad de herramientas de informes y ORM, y aumenta un poco la complejidad general de la solución. No hay demasiados desarrolladores por ahí que estén íntimamente familiarizados con los UDT, y nunca he visto UDT administrados utilizados fuera de los ejemplos.
Uno de los mejores ejemplos de un tipo que se realiza mejor como UDT (si aún no existía) tendría que ser
hierarchyid
( enlace MSDN ). Para seguir siendo eficiente, almacena su valor en un formato binario (a diferencia de las implementaciones personalizadas de varchar habituales), que sería difícil de mantener sin las funciones del tipo. Los aproximadamente 10 métodos que proporciona el tipo también se proporcionan mejor como parte del tipo, en lugar de las funciones externas. Consideraría el uso de UDT administrado personalizado en casos como este, donde hay una ganancia significativa al proporcionar una implementación eficiente y ordenada como un tipo separado.fuente
Una pregunta / respuesta más práctica. ¿Su empresa permite usarlo?
¿Es su empresa trabajando con varias marcas DBSQL que manejan diferentes DDL?
Cada marca de base de datos puede ofrecer buenas funciones adicionales, como los tipos definidos por el usuario, pero si su empresa usa varios DB, puede tener problemas con las funciones no estándar.
Si la empresa es solo usted, o puede decidir qué bases de datos y características va a utilizar, puede usar DDL
Tengo trabajo con varios proyectos en los que un tipo definido por el usuario podría ser útil, pero debería apegarme a más características estándar, ya que tuvimos que lidiar con varios DB. (s)
fuente