sql-server - ¿Cuáles son las mejores prácticas para usar un GUID como clave principal, específicamente con respecto al rendimiento?




entity-framework database-design primary-key (5)

Tengo una aplicación que usa GUID como clave principal en casi todas las tablas y he leído que hay problemas sobre el rendimiento al usar GUID como clave principal. Honestamente, no he visto ningún problema, pero estoy a punto de iniciar una nueva aplicación y todavía quiero usar los GUID como claves principales, pero estaba pensando en usar una clave principal compuesta (el GUID y quizás otro campo) .)

Estoy usando un GUID porque son agradables y fáciles de administrar cuando tiene diferentes entornos como las bases de datos de "producción", "prueba" y "dev", y también para la migración de datos entre bases de datos.

Usaré Entity Framework 4.3 y quiero asignar el Guid en el código de la aplicación, antes de insertarlo en la base de datos. (es decir, no quiero que SQL genere el Guid).

¿Cuál es la mejor práctica para crear claves primarias basadas en GUID, para evitar los supuestos éxitos de rendimiento asociados con este enfoque?


Answers

Actualmente estoy desarrollando una aplicación web con EF Core y aquí está el patrón que utilizo:

Todas mis clases (tablas) y un int PK y FK. Tengo una columna adicional con el tipo Guid (generado por el constructor c #) con un índice no agrupado.

Todas las uniones de la tabla dentro de EF se gestionan a través de las teclas int, mientras que todos los accesos desde el exterior (controladores) se realizan con las Guías.

Esta solución permite no mostrar las claves int en las URL, pero mantener el modelo ordenado y rápido.


Este enlace lo dice mejor de lo que podía y me ayudó en la toma de decisiones. Normalmente opto por un int como clave principal, a menos que tenga una necesidad específica de no hacerlo y también permito que el servidor SQL genere / mantenga este campo a menos que tenga alguna razón específica para no hacerlo. En realidad, las preocupaciones de rendimiento deben determinarse en función de su aplicación específica. Hay muchos factores en juego aquí que incluyen, entre otros, el tamaño de db esperado, la indexación adecuada, la consulta eficiente y más. Aunque la gente puede estar en desacuerdo, creo que en muchos escenarios no notará una diferencia con ninguna de las opciones y debe elegir qué es más apropiado para su aplicación y qué le permite desarrollarse de manera más fácil, más rápida y más eficaz ¿Qué diferencia hace el resto :).

https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

PD: No estoy seguro de por qué usaría un PK compuesto o qué beneficio cree que le daría.


He estado utilizando GUID como PK desde 2005. En este mundo de base de datos distribuida, es absolutamente la mejor manera de combinar datos distribuidos. Puede disparar y olvidarse de las tablas de combinación sin la preocupación de que las coordenadas coincidan en las tablas unidas. Las combinaciones de GUID se pueden copiar sin ninguna preocupación.

Esta es mi configuración para usar GUIDs:

  1. PK = GUID. Los GUID se indexan de manera similar a las cadenas, por lo que las tablas de filas altas (más de 50 millones de registros) pueden necesitar particiones de tablas u otras técnicas de rendimiento. SQL Server se está volviendo extremadamente eficiente, por lo que las preocupaciones de rendimiento son cada vez menos aplicables.

  2. PK Guid es un índice NO agrupado. Nunca agrupe el índice de un GUID a menos que sea NewSequentialID. Pero incluso entonces, un reinicio del servidor causará grandes interrupciones en el pedido.

  3. Agregue ClusterID Int a cada tabla. Este es su índice CLUSTERED ... que ordena su mesa.

  4. Unirme a ClusterIDs (int) es más eficiente, pero trabajo con 20-30 millones de tablas de registro, por lo que unirme a GUID no afecta visiblemente el rendimiento. Si desea un rendimiento máximo, use el concepto ClusterID como su clave principal y únase a ClusterID.

Aquí está mi tabla de correo electrónico ...

CREATE TABLE [Core].[Email] (

[EmailID]      UNIQUEIDENTIFIER CONSTRAINT [DF_Email_EmailID] DEFAULT (newsequentialid()) NOT NULL,

[EmailAddress] NVARCHAR (50)    CONSTRAINT [DF_Email_EmailAddress] DEFAULT ('') NOT NULL,

[CreatedDate]  DATETIME         CONSTRAINT [DF_Email_CreatedDate] DEFAULT (getutcdate()) NOT NULL,

[ClusterID] INT NOT NULL IDENTITY,
    CONSTRAINT [PK_Email] PRIMARY KEY NonCLUSTERED ([EmailID] ASC)
);
GO

CREATE UNIQUE CLUSTERED INDEX [IX_Email_ClusterID] ON [Core].[Email] ([ClusterID])
GO

CREATE UNIQUE NonCLUSTERED INDEX [IX_Email_EmailAddress] ON [Core].[Email] ([EmailAddress] Asc)

Si usa GUID como clave principal y crea un índice agrupado, sugiero usar el valor predeterminado de NEWSEQUENTIALID ()


Se dieron buenas respuestas técnicas de una manera mejor de lo que puedo hacer. Solo puedo agregar a este tema:

Si desea algo que no esté permitido / aceptable, es una buena razón para dar un paso atrás.

  1. Comprender el núcleo de por qué no es aceptable.
  2. Cavar más en documentación / artículos de revistas / web y etc.
  3. Analizar / revisar el diseño actual y señalar fallas importantes.
  4. Considere y pruebe cada paso durante el nuevo diseño.
  5. Siempre mira hacia adelante y trata de crear una solución adaptativa.

Espero que ayude a alguien.





sql-server entity-framework database-design primary-key guid