Stockage de la date sous forme d'entier (numérique), quels sont les avantages

11

question 1

Je travaille avec un système où la date est stockée sous forme d'entier (numérique réel (8,0)) et j'ai remarqué que d'autres systèmes stockent également la date en tant qu'int comme cisco dans ce fil . Exemple

20120101  -- 01 Jan 2012

Y a-t-il un avantage à conserver le système de date numérique et à ne pas utiliser SQL Datetime?

question 2

Maintenant, j'essaie de parcourir la date numérique pour trouver des clients entre deux dates. Si le startet enddateenglobe deux mois, j'obtiens des milliers d'enregistrements au lieu de seulement 60. Exemple:

create table #temp1(day int,capacity int) /* just a temp table */

declare @start int 
declare @end int

set @start=20111201
set @end = 20120131

while (@start <= @end) 
Begin
    insert into #temp1  /* I am storing things in #temp table so data looks pretty */
    exec usp_GetDailyCap @date1= @start

    set @start = @start + 1;    
end

select * from #temp1

Cela tire 8931 enregistrements au lieu de 60. Existe-t-il un meilleur moyen d'améliorer la logique ci-dessus, donc je ne tire que des dates valides? J'ai essayé IsDate et les sous-requêtes mais cela n'a pas fonctionné de manière efficace.

Jackofall
la source
Si vous exécutez SQL Server 2008 ou supérieur, vous pouvez simplement utiliser le type de données Date. Il est un peu plus petit et ne vous oblige pas à inclure le temps, mais presque toutes les fonctions datetime de SQL fonctionnent toujours pour cela.
DForck42
2
Je ne vois que des inconvénients dans cette approche, aucun avantage du tout
a_horse_with_no_name

Réponses:

11

Pour répondre à votre première question, je recommanderais d'utiliser le DATETIMEtype de données dans SQL Server. Pas nécessairement pour des raisons de performances, mais pour tirer parti des fonctionnalités spécifiques au SGBDR. Par exemple, vous devez réinventer beaucoup de logique juste pour faire des mathématiques de la date de base (pensez DATEDIFF(), DATEADD(), DATEPART()et bien d' autres fonctions. Ils sont évidemment adaptées au DATETIMEtype de données et sont faciles à travailler avec).

Quant à votre deuxième question, vous rencontrez le problème exact vers lequel la première question (et ma réponse) est orientée . Vous regardez 20111201 et 20120131 comme dates, et votre cerveau vous dit que cela devrait être une différence de 60 jours. Eh bien, vous bouclez en fonction du delta ... qui est:

20120131 - 20111201 = 8930 (avec la boucle inclusive ce sera 8931)

En d'autres termes, votre WHILEboucle s'exécute 8931 fois. Cela se produit car ce sont des valeurs entières et votre boucle ne sautera pas de 20111231 directement à 20120101.

Vos entiers ne vont pas prendre en compte le plafond des années et des mois (c'est-à-dire votre problème de question 2 ).

Thomas Stringer
la source
Eh bien, c'est exactement ma question. Pour les dates numériques, les boucles peuvent aller en milliers, pas seulement 30 jours ou 29 jours. Mais gardez à l'esprit que je travaille avec un système professionnel . Et même Cisco l'utilise comme il semble.
Jackofall
4
Outre les performances et les fonctionnalités, il y a également l'intégrité. Avec des entiers comme les dates, le db permettrait 20121301et 20120230et même 20129999comme une date.
ypercubeᵀᴹ
@Jackofall Cisco n'a pas la plate-forme d'un SGBDR derrière. Ils ont écrit leur propre logique. Pourquoi n'utiliseraient- ils pas simplement des entiers. À partir de zéro, c'est probablement le moyen le plus simple pour les logiciels de bas niveau. Mais nous parlons ici de pommes et d'oranges.
Thomas Stringer
3
@Jackofall: Il y a une grande différence entre le stockage de dates sous forme d'entiers (et d'avoir des lacunes) et le stockage d'heures et d'horodatages sous forme d'entiers - ou même des dates sous forme d'entiers, comme le fait VB / Excel.
ypercubeᵀᴹ
4
Il existe de nombreuses (sinon la plupart) bases de données conçues par des professionnels qui utilisent de mauvaises techniques. J'ai travaillé avec de nombreux produits COTS et je n'en ai vu aucun qui était bien défini du point de vue de la base de données.
HLGEM
6
  1. Ralph Kimball recommande de stocker les dates sous forme d'entiers. Il a beaucoup écrit, à la fois des articles en ligne et des livres.
  2. Vous pouvez utiliser une table de calendrier et attribuer des numéros consécutifs à vos dates, comme suit:

    Numéro de date

    20120229 1234

    20120301 1235

Le tableau de calendrier doit être généré, mais c'est une tâche très simple.

AK
la source
1
J'aimerais voir le cas où vous filtrez une requête en vous joignant à une table de dates avec les dates stockées sous forme numérique et en filtrant ces dates numériques battrait en utilisant "où [date] entre @startdate et @enddate"
DForck42
1
@ DForck42 il n'est pas nécessaire que le cas que vous proposez: "où [dateAsInt] entre 20120229 et 20120329" renvoie exactement les mêmes lignes que "où [date] entre '20120229' et '20120329'"
AK
3
Et quel était son raisonnement?
HLGEM
5

Types de données potentiels et leurs tailles / limitations:

  • Décimal (8,0): 5 octets
  • Date: 3 octets, 0001-01-01 à 9999-12-31
  • Int: 4 octets

Avantages pour le type de données numérique:

  • Ils sont jolis?

Inconvénients pour le type de données numériques:

  • Nécessite un code personnalisé pour gérer les opérations de date
  • Nécessite un code personnalisé pour gérer les dates correctes (c'est-à-dire, ne pas autoriser 20120230 [30 février 2012])
  • Plus grande empreinte de données par rapport au type de données Date.

Honnêtement, il vaut mieux utiliser le type de données de date IMHO.

DForck42
la source