sql >> Base de Datos >  >> RDS >> Sqlserver

datetime vs smalldatetime en SQL Server:¿Cuál es la diferencia?

Este artículo explora las principales diferencias entre datetime y pequeña fecha y hora tipos de datos en SQL Server.

Ambos tipos de datos se utilizan para almacenar valores de fecha y hora; sin embargo, existen diferencias entre los dos. En la mayoría de los casos, es mejor evitar ambos tipos y usar datetime2 en su lugar (Microsoft también recomienda esto). En cualquier caso, aquí hay una comparación de estos dos tipos de datos.

La siguiente tabla describe algunas similitudes y diferencias clave entre estos dos tipos de datos.

Característica pequeña fecha y hora fechahora
Cumple con SQL (ANSI e ISO 8601) No No
Intervalo de fechas 1900-01-01 a 2079-06-06 1753-01-01 a 9999-12-31
Intervalo de tiempo 00:00:00 a 23:59:59 00:00:00 a 23:59:59.997
Longitud de caracteres 19 posiciones como máximo 19 posiciones mínimo
23 máximo
Tamaño de almacenamiento 4 bytes, fijo 8 bytes, fijo
Precisión Un minuto Redondeado a incrementos de .000, .003 o .007 segundos
Precisión de fracciones de segundo No
Precisión fraccionaria de segundo definida por el usuario No No
Compensación de zona horaria Ninguno Ninguno
Reconocimiento y preservación de la compensación de zona horaria No No
Consciente del horario de verano No No

¿Debería usar 'datetime' o 'smalldatetime'?

Microsoft recomienda no usar estos dos tipos de datos para trabajos nuevos. Solo debe usarlos si tiene una buena razón para hacerlo.

Pero si tuviera que elegir, su decisión probablemente se tomaría sopesando la precisión adicional y la exactitud de datetime frente a los requisitos de almacenamiento más bajos de smalldatetime .

En otras palabras, si no necesita precisión en segundos, smalldatetime hará el trabajo usando solo la mitad del espacio de almacenamiento. Por otro lado, si necesita precisión en segundos (o incluso algunas fracciones de segundo), deberá usar datetime .

En cualquier caso, Microsoft recomienda usar fecha , tiempo , fechahora2 o datetimeoffset para obra nueva.

Ver smalldatetime frente a fechahora2 y fechahora frente a fechahora2 para ver cómo cada uno de estos tipos se compara con datetime2 .

Ejemplo 1:comparación básica

Aquí hay un ejemplo rápido para demostrar la diferencia básica entre datetime y pequeña fecha y hora .

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.555';
SET @thesmalldatetime = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:

+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Aquí, establecí un smalldatetime variable al mismo valor que la fecha y hora variable. Esto hace que el valor se convierta a smalldatetime y luego podemos usar un SELECT declaración para ver el valor real que se asignó a cada variable.

En este caso, ambas variables redondean el valor. Pero se redondean de manera diferente.

La fechahora variable redondea hacia arriba la parte de los segundos fraccionarios. Esto se debe a que datetime siempre redondea a incrementos de .000, .003 o .007 segundos.

La pequeña fecha y hora variable por otro lado, redondea hacia arriba los minutos parte. No solo eso, la parte de los segundos se pone a cero. Esto es de esperar, porque la documentación oficial de Microsoft establece que smalldatetime El tiempo de es ...basado en un día de 24 horas, con segundos siempre cero (:00) y sin fracciones de segundo .

Entonces podemos ver que la fecha y hora type proporciona un valor de fecha/hora más preciso y exacto.

Ejemplo 2:configuración de valores a partir de literales de cadena

En los ejemplos anteriores, el smalldateime el valor se asignó estableciéndolo en el mismo valor que la fecha y hora valor. Cuando hacemos eso, SQL Server realiza una conversión implícita para que los datos "encajen" en el nuevo tipo de datos.

Resulta que también podemos establecer el smalldatetime variable al mismo literal de cadena que incluye segundos fraccionarios (aunque este tipo de datos no almacena segundos fraccionarios).

Aquí hay un ejemplo donde hago precisamente eso:

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.555';
SET @thesmalldatetime = '2025-05-21 10:15:30.555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:

+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Por supuesto, el resultado es el mismo cuando seleccionamos los valores:smalldatetime el valor no muestra fracciones de segundo, los segundos son cero y los minutos se redondean.

Sin embargo, si usamos más de 3 decimales, ambos tipos de datos devolverán un error.

Error para fecha y hora :

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.5555';
SET @thesmalldatetime = '2025-05-21 10:15:30.5555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:

Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.

Error para smalldatetime :

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.5555';
SET @thesmalldatetime = '2025-05-21 10:15:30.5555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:

Msg 295, Level 16, State 3, Line 5
Conversion failed when converting character string to smalldatetime data type.

Ejemplo 3:tamaño de almacenamiento

La pequeña fecha y hora tipo de datos tiene un tamaño de almacenamiento fijo de 4 bytes. Este es uno de los pocos beneficios smalldatetime tiene más de datetime , que tiene un tamaño de almacenamiento fijo de 8 bytes.

Podemos verificar el tamaño de almacenamiento usando DATALENGTH() función para devolver el número de bytes utilizados para cada uno de nuestros valores:

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thesmalldatetime = @thedatetime;
SELECT 
  DATALENGTH(@thedatetime) AS 'datetime',
  DATALENGTH(@thesmalldatetime) AS 'smalldatetime';

Resultado

+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+

También obtenemos el mismo resultado incluso si los convertimos a varbinary , que es más representativo de cómo se almacenan realmente en la base de datos:

DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thesmalldatetime = @thedatetime;
SELECT 
  DATALENGTH(CAST(@thedatetime AS varbinary(10))) AS 'datetime',
  DATALENGTH(CAST(@thesmalldatetime AS varbinary(10))) AS 'smalldatetime';

Resultado

+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+