Question

Lequel:

est la recommandé moyen de stocker date et l'heure dans SQL Server 2008 +?

Je suis conscient des différences de précision (et l'espace de stockage sans doute), mais en ignorant ceux pour l'instant, est-il un meilleur document de pratique quand utiliser ce, ou peut-être que nous devrions utiliser datetime2 seulement?

Était-ce utile?

La solution

La documentation MSDN pour datetime recommande d'utiliser datetime2 . Voici leur recommandation:

  

Utilisez le time, date, et datetime2   types de données datetimeoffset pour les nouveaux   travail. Ces types alignent avec SQL   La norme. Ils sont plus mobiles.   time, datetime2 et datetimeoffset   fournir une précision plus secondes.   datetimeoffset fournit le fuseau horaire   soutien à l'échelle mondiale déployée   applications.

datetime2 a une plus grande plage de dates, une précision fractionnelle par défaut plus grande, et en option la précision spécifiée par l'utilisateur. En outre, selon la précision spécifiée par l'utilisateur, il peut utiliser moins de stockage.

Autres conseils

DATETIME2 a une plage de dates "0001/01/01" à "9999/12/31" alors que le type de DATETIME ne supporte que l'année 1753-9999.

En outre, si vous avez besoin, DATETIME2 peut être plus précis en termes de temps; DATETIME est limitée à 3 1/3 millisecondes, alors que DATETIME2 peut être précis jusqu'à 100 ns.

Les deux types de carte System.DateTime dans .NET - il pas de différence

.

Si vous avez le choix, je vous conseille d'utiliser DATETIME2 chaque fois que possible. Je ne vois aucun avantage à l'aide DATETIME (sauf pour la compatibilité descendante) -. Vous aurez moins de problèmes (avec les dates étant hors de portée et sans tracas comme ça)

Plus: si vous avez besoin de la date (sans partie de temps), utiliser la date - il est tout aussi bon que DATETIME2 et vous fait gagner l'espace, aussi! :-) la même chose pour le temps seulement - utiliser TIME. C'est ce que ces types sont là pour ça!

datetime2 gagne dans la plupart des aspects, sauf (anciennes applications de compatibilité)

  1. Agrandir plage de valeurs
  2. meilleure Précision
  3. petit espace de stockage (si option précision spécifiée par l'utilisateur est spécifiée)

Date de SQL et les types de données temps comparer - datetime, datetime2, date, heure

S'il vous plaît noter les points suivants

  • Syntaxe
    • datetime2 [(secondes fractionnaires précision => Voir ci-dessous la taille de stockage)]
  • Précision, échelle
    • 0 à 7 chiffres, avec une précision de 100 ns.
    • La précision par défaut est de 7 chiffres.
  • Taille de stockage
    • 6 octets pour une précision inférieure à 3;
    • 7 octets pour la précision 3 et 4.
    • Tous les autres précision nécessitent 8 octets .
  • DateTime2 (3) ont le même nombre de chiffres que DateTime mais utilise 7 octets de stockage au lieu de 8 octets ( SQLHINTS- DateTime vs dateTime2 )
  • En savoir plus sur datetime2 (Transact-SQL de l'article MSDN)

source d'image: SCTM Kit de formation auto-rythmées (examen 70-432): Microsoft® SQL Server® 2008 - Mise en œuvre et maintenance Chapitre 3: Tableaux -> Leçon 1: Création de tableaux -> Page 66

I Concurr avec @marc_s et @Adam_Poward - DateTime2 est le procédé préféré de l'avant. Il dispose d'une plage de dates plus large, plus de précision et utilise un stockage égale ou inférieure (selon la précision).

Une chose la discussion manquée, mais ... @Marc_s déclare: Both types map to System.DateTime in .NET - no difference there. Ceci est correct, cependant, l'inverse est pas vrai ... et il importe lors des recherches de la plage de dates (par exemple « me trouver tous les enregistrements modifiés sur 5/5/2010 »).

La version de .NET de Datetime a une portée similaire et précision DateTime2. Mapper une .net Datetime vers le bas à l'ancienne SQL DateTime arrondi implicite se produit . L'ancien DateTime SQL est précise à 3 millisecondes. Cela signifie que 11:59:59.997 est aussi proche que vous pouvez obtenir à la fin de la journée. Tout ce qui est plus arrondi au jour suivant.

Essayez ceci:

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

Éviter cette arrondi implicite est une raison importante pour passer à DateTime2. l'arrondissement implicite des dates provoque clairement la confusion:

Presque toutes les réponses et les commentaires ont été lourds sur les avantages et les inconvénients sur la lumière. Voici un résumé de tous les avantages et les inconvénients à ce jour, plus quelques inconvénients cruciaux (en 2 ci-dessous), je ne l'ai vu mentionné une fois ou pas du tout.

  1. PROS:

1.1. Plus conforme ISO (ISO 8601) (bien que je ne sais pas comment cela entre en jeu dans la pratique).

1.2. Plus gamme (1/1/0001 à 12/31/9999 contre 1/1 / 1753-1712 / 31/9999) (bien que la gamme supplémentaire, tous avant 1753, ne sera probablement pas utilisé, sauf par ex., dans historique, astronomique, géologique, etc. applications).

1.3. correspond exactement à la gamme de la gamme Type de DateTime de .NET (bien que les deux reconvertir en arrière sans codage spécial si les valeurs se situent dans la gamme de type de cible et de précision, sauf pour Con # 2.1 ci-dessous SINON Erreur / arrondi se produira).

1,4. Plus de précision (100 nanosecondes aka 0.000,000,1 sec. Par rapport à 3,33 milliseconde aka 0.003,33 sec.) (Même si la précision supplémentaire ne sera probablement pas utilisé, sauf par ex., En ingénierie / applications scientifiques).

1,5. Lorsqu'il est configuré pour similaire (comme dans 1 milliseconde pas « même » (comme dans 3,33 millisecondes) comme Iman Abidi a revendiqué) de précision que DateTime, utilise moins d'espace (7 vs 8 octets), puis de bien sûr, vous seriez perdre le bénéfice de précision qui est probablement l'une des deux (l'autre plage de l'être) la plus vantée mais les avantages inutiles probables).

  1. CONS:

2.1. Lors du passage d'un paramètre à un SqlCommand .NET, vous devez spécifier System.Data.SqlDbType.DateTime2 si vous passerez une valeur hors de la plage et / ou la précision de SQL Server DateTime, car il est par défaut à System.Data.SqlDbType.DateTime.

2.2. Ne peut pas être implicitement / facilement converti en une valeur numérique à virgule flottante (Nombre de jours depuis min date-heure) pour effectuer les opérations suivantes à / avec elle dans les expressions SQL Server à l'aide des valeurs numériques et les opérateurs:

2.2.1. ajouter ou soustraire de jours ou jours partiels. Remarque:. L'utilisation DateAdd fonction comme une solution de contournement n'est pas trivial lorsque vous besoin d'envisager plusieurs si toutes les parties de la date-heure

2.2.2. prendre la différence entre deux dates fois à des fins de calcul « âge ». Remarque: Vous ne pouvez pas simplement utiliser DateDiff de SQL Server de fonction à la place, car il ne calcule pas age comme la plupart des gens attendent en ce que si les deux dates fois croiserait une limite date-heure calendrier / horloge des unités spécifiées si même pour un minuscule fraction de cette unité, il retournera la différence que 1 de cette unité par rapport à 0. Par exemple, le DateDiff dans les années Day de deux fois ce jour seulement 1 milliseconde en dehors retournera 1 contre 0 (jours) si ces date- les temps sont différents jours civils (par exemple « 1999-12-31 23: 59: 59,9999999 » et « 2000-01-01 00: 00: 00,0000000 »). Les mêmes 1 milliseconde fois la date différence si elle est déplacée afin qu'ils ne se croisent pas un jour de calendrier, retournera un « DateDiff » dans les années de 0 Day (jours).

2.2.3. prendre la Avg de la date fois (dans une requête globale) en convertissant simplement « flotter » d'abord, puis de nouveau à DateTime.

NOTE: Pour convertir DateTime2 à un numérique, vous devez faire quelque chose comme la formule suivante qui suppose encore vos valeurs ne sont pas moins que l'année 1970 (ce qui signifie que vous perdez toute la gamme supplémentaire, plus de 217 ans. . Remarque: vous ne pouvez pas être en mesure de régler simplement la formule pour permettre une gamme supplémentaire parce que vous pouvez rencontrer des problèmes de dépassement numériques

25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0 - Source: « https : //siderite.blogspot.com/2015/08/how-to-translate-t-sql-datetime2-to.html «

Bien sûr, vous pouvez également Cast à DateTime premier (et le cas échéant à nouveau à DateTime2), mais vous perdriez la précision et la portée (tous avant 1753) les prestations de DateTime2 contre DateTime qui sont prolly les 2 plus grands et aussi en même temps prolly le 2 moins probablement nécessaire qui pose la question pourquoi l'utiliser quand vous perdez les conversions implicites / faciles à numérique à virgule flottante (nombre de jours) pour l'addition / soustraction / « âge » (par rapport à DateDiff) / Avg avantage CALC qui est un grand dans mon expérience.

BTW, la Avg de la date-temps est (ou au moins devrait être) un important cas d'utilisation. a) En plus de l'utilisation à obtenir la durée moyenne lorsque la date fois (depuis une date-heure de base commune) sont utilisés pour représenter la durée (une pratique courante), b) il est également utile pour obtenir une statistique de type tableau de bord sur ce que la date- moyenne le temps est dans la colonne date-heure d'une plage / groupe de lignes. c) Une norme (ou au moins devrait être standard) requêtes ad-hoc pour surveiller / Dépanner les valeurs dans une colonne qui peut ne pas être valide jamais / plus et / ou peut devoir être dépréciée est liste pour compter chaque valeur l'occurrence et (le cas échéant) les Min, Avg et horodatés Max associée à cette valeur.

DateTime2 fait des ravages si vous êtes un développeur d'accès à essayer d'écrire maintenant () sur le terrain en question. Tout a fait un accès -> SQL 2008 R2 migration et mettre tous les champs datetime en tant que DateTime2. Un enregistrement avec l'ajout maintenant () comme valeur bombardée. Il était d'accord sur 1/1/2012 14:53:04, mais pas sur 1/10/2012 14:53:04.

Une fois que le caractère a fait la différence. Il aide quelqu'un l'espoir.

Voici un exemple qui va vous montrer les différences de taille de stockage (octets) et la précision entre smalldatetime, datetime, datetime2 (0), et datetime2 (7):

DECLARE @temp TABLE (
    sdt smalldatetime,
    dt datetime,
    dt20 datetime2(0),
    dt27 datetime2(7)
)

INSERT @temp
SELECT getdate(),getdate(),getdate(),getdate()

SELECT sdt,DATALENGTH(sdt) as sdt_bytes,
    dt,DATALENGTH(dt) as dt_bytes,
    dt20,DATALENGTH(dt20) as dt20_bytes,
    dt27, DATALENGTH(dt27) as dt27_bytes FROM @temp

qui retourne

sdt                  sdt_bytes  dt                       dt_bytes  dt20                 dt20_bytes  dt27                         dt27_bytes
2015-09-11 11:26:00  4          2015-09-11 11:25:42.417  8         2015-09-11 11:25:42  6           2015-09-11 11:25:42.4170000  8

Donc, si je veux stocker des informations à la seconde - mais pas à la milliseconde -. Je peux économiser 2 octets, si j'utilise datetime2 (0) au lieu de datetime ou datetime2 (7)

Interprétation des chaînes de date dans datetime et datetime2 peut être différent aussi, lorsque vous utilisez les paramètres de DATEFORMAT non-américains. Par exemple.

set dateformat dmy
declare @d datetime, @d2 datetime2
select @d = '2013-06-05', @d2 = '2013-06-05'
select @d, @d2

retourne 2013-05-06 (à savoir 6 mai) pour datetime et 2013-06-05 (à savoir 5 Juin) pour datetime2. Cependant, avec dateformat mis à mdy, à la fois @d et le retour de @d2 2013-06-05.

Le comportement datetime semble en contradiction avec la documentation MSDN de SET DATEFORMAT qui stipule que: Certaines chaînes de caractères formats, par exemple ISO 8601, sont interprétées indépendamment du réglage DATEFORMAT . De toute évidence, pas vrai!

Jusqu'à ce que je suis mordu par cela, je avais toujours pensé que les dates de yyyy-mm-dd seraient simplement seraient traités, quels que soient les paramètres de langue / locale.

alors qu'il augmente précision datetime2 , certains clients ne prennent pas en charge date , temps , ou datetime2 et vous forcer à se convertir à une chaîne littérale. Plus précisément Microsoft mentionne ODBC "niveau bas", OLE DB, JDBC, et les problèmes de SqlClient avec ces types de données et a une tableau montrant comment chacun peut cartographier le type.

Si la valeur compatibilité sur la précision, utilisez datetime

Vieille question ... Mais je veux ajouter quelque chose de pas déjà dit par quelqu'un ici ... (Note: Ceci est ma propre observation, il ne demande pas de référence)

Datetime2 est plus rapide quand il est utilisé dans les critères de filtre.

TLDR:

Dans SQL 2016 j'avais une table avec cent mille lignes et une colonne datetime ENTRY_TIME parce qu'il était nécessaire de stocker l'heure exacte jusqu'à secondes. Lors de l'exécution d'une requête complexe avec de jointures et une sous requête, quand je clause where:

WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'

La requête était bien au début quand il y avait des centaines de lignes, mais quand le nombre de lignes a augmenté, la requête a commencé à donner cette erreur:

Execution Timeout Expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.

J'ai supprimé la clause where, et de façon inattendue, la requête a été exécutée en 1 sec, bien que maintenant TOUTES les lignes pour toutes les dates ont été extraites. Je lance la requête interne avec clause where, et il a fallu 85 secondes, et sans clause where il a fallu 0.01 secondes.

Je suis tombé sur beaucoup de discussions ici pour cette question comme les performances de filtrage dateheure

I optimisé requête d'un bit. Mais la vitesse réelle, je suis arrivé était en changeant la colonne datetime à datetime2.

Maintenant, la même requête qui a expiré prend déjà moins d'une seconde.

hourras

Selon cet article , si vous souhaitez avoir la même précision de DateTime en utilisant DateTime2 il vous suffit d'utiliser DateTime2 (3). Cela devrait vous donner la même précision, prendre un moins d'octets, et de fournir une gamme élargie.

Je viens de tombé sur un autre avantage pour DATETIME2: il évite un bug dans le module adodbapi Python, qui explose si une bibliothèque standard valeur datetime est passé qui a non nuls microsecondes pour une colonne de DATETIME mais fonctionne très bien si la colonne est défini comme DATETIME2.

Select ValidUntil + 1
from Documents

Le SQL ci-dessus ne fonctionne pas avec un champ DateTime2. Il retourne et erreur "choc de type Opérande: datetime2 est incompatible avec int"

Ajout 1 pour obtenir le lendemain est quelque chose développeurs ont fait avec des dates pendant des années. Maintenant, Microsoft a un super nouveau champ datetime2 qui ne peut pas gérer cette fonctionnalité simple.

« Nous allons utiliser ce nouveau type qui est pire que l'ancien », je ne pense pas!

Je pense que DATETIME2 est la meilleure façon de stocker le date, car il a plus d'efficacité que le DATETIME. En SQL Server 2008 vous pouvez utiliser DATETIME2, il stocke une date et l'heure, prend 6-8 bytes pour stocker et a une précision de 100 nanoseconds. Donc, toute personne qui a besoin d'une plus grande précision de temps voudra DATETIME2.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top