2009-06-25 20 views
9

Tenemos que guardar el día y el mes de un evento recurrente anual. (Piénselo como el día de su año en que la factura debe enviarse al cliente.)La mejor manera de guardar solo día y mes en la base de datos

Tendremos que hacer algunos cálculos con esta información. Por ejemplo, si el cliente paga dos veces al año. Entonces no solo debemos verificar si este día es hoy sino también si este día es en 6 meses.

Ahora tenemos varias opciones: a) Guardamos la información en un campo FECHA pero ignoramos el año. b) Creamos dos campos int en la base de datos date_day y date_month. c) Creamos un campo varchar y luego realizamos una expresión regular y una división, p. 31.12 cada vez que hacemos algún cálculo.

Hicimos varias pruebas y descubrimos que c) es definitivamente demasiado lento. Pero todavía tenemos la opción a) y b). Primero queríamos ir por b) pero después de algunas pruebas tendemos más a a).

¿Hay una buena razón técnica que realmente haría una opción mucho mejor que la otra?

(Estamos utilizando MySQL por el momento. Si esto es de importancia.)

Respuesta

9

yo elegiría b), ya que refleja con mayor precisión el significado de los datos. Tener una estructura de datos donde se supone que algunas partes deben "ignorarse" es problemático. ¿Qué pasa si la gente simplemente hace una comparación simple de fechas, suponiendo que el año sea siempre el mismo, pero alguien usó un año distinto, asumiendo que el año no importa de todos modos?

Utilice siempre estructuras de datos que reflejen sus intenciones.

Que c) es malo es, creo, más allá de una discusión razonable :-). Y no estoy pensando en razones de rendimiento ...

+0

acordado, que tiene un campo de datos donde se supone que partes de él para ser ignorado son muy malos y probablemente te morderán en el futuro. Yo voto por la opción b. –

+0

Sí, el año no importa. Ya tenemos una fecha de inicio del contrato y una fecha de finalización del contrato. Solo tenemos que calcular si se debe enviar una factura. Y la primera selección que estamos haciendo es verificar si "hoy" está dentro de la fecha de inicio y la fecha de finalización. Solo entonces comprobamos si tenemos que generar una factura hoy. –

0

También me pondría de lado con b), pero uso TINYINT para el mes (0 a 255) y SMALLINT (-32,768 a 32,767) por año para ahorrar un poco espacio.

0

Elija UN campo int como 1601 para el 1 de enero.

+0

¿Cuál es la diferencia significativa entre esta opción y "31.12"? –

+0

cálculo en lugar de manipulación de cadena –

+0

Correcto, pero también podría almacenarlo como un número real –

1

Elegir b), porque facilitaría las consultas: podrá restaurar todos los eventos en un rango (diciembre, día específico, rango de días) de una manera muy fácil. Si elige a), no olvide configurar el año en uno específico por motivos de comparación y extracción.

2

Usaría el campo de fecha y, aunque no fuera necesario, igual ahorraría el año. Solo quítelo cuando tenga que imprimirlo/usarlo. Hay algunas razones:

  1. Es posible descubrir que una tarde punto de que el cliente no quiere que ahorra la fecha. En ese caso, usted no tiene que hacer ningún cambio en su estructura de base de datos .
  2. Puede usar las funciones de fecha SQL para comparar fechas, si es necesario. Si tiene un día y un mes en campos separados, necesita mucho más código, por ejemplo, calcule la diferencia entre dos fechas (años bisiestos, etc.).

Las razones para elegir b) también se pueden resolver fácilmente con esas funciones de fecha SQL. Puede seleccionar eventos en un determinado mes, por ejemplo, en una sola consulta.

+0

Gracias por recordarme sobre los años bisiestos. Esto me hizo darme cuenta de que olvidábamos tratar el febrero de manera diferente. incluso necesitamos d algo como "último día del mes" como una opción para los usuarios. Este comentario me ayudó mucho.Incluso si decidimos continuar por b) –

1

Almacenaba la fecha del primer evento, y luego un intervalo para cada evento posterior, como la mayoría de las aplicaciones de calendario. En este caso, usted estructurar así:

first_event | interval | interval_unit 
-------------+-------------------------- 
    2009-01-01 |  6 | 'month' 
    2009-02-01 |  1 | 'year' 

Desafortunadamente, MySQL no tiene un tipo de datos INTERVAL, por lo que dos columnas y será necesario un poco de post-procesamiento, pero creo que es el más forma flexible de abordar el problema.

+0

Ya tenemos el intervalo y la unidad de intervalo. La pregunta es más acerca de cómo guardar el primer evento si el año no es "importante". Lo que me gustaría saber es si un campo de fecha es realmente la mejor opción para el postprocesamiento. (Tal vez mi respuesta a "sleske" le brinde más información.) –

+0

Creo que hará los cálculos mucho más fáciles si almacena el primer evento como DATE. Si siempre tuviera intervalos de un año, tener solo una columna MES y DÍA tendría sentido, pero como sus intervalos pueden cambiar (¿y si quiere facturar a alguien todos los meses?), Elegiría un calendario. . –

0

me gustaría ir para el número de días de año (por ejemplo, un único número de 0 a 365, y luego añadir que, para el 1 de enero del año en particular le interesa.

Si no quiero hacer los cálculos adicionales de la solución anterior, luego use dos campos uno por mes y uno por día (¡pero asegúrese de actualizar ambos cuando lo necesite!).

Recuerde, debe tratar con años bisiestos, por lo que utilizar un campo de fecha es una mala idea ya que tendría que almacenar fechas con dos años, uno por año bisiesto y otro no muy complicado!

+1

Los años bisiestos son precisamente la razón por la que 'día del año' no funcionaría para esto: si almacenó '60', en años bisiestos pagaría el 29 de febrero, en años no bisiestos, en el Partido 1: los cronogramas de pagos del mundo real no no hagas eso – AakashM

+0

Es cierto, aunque no depende de las reglas comerciales. Creo que cambiaría el número del día del año una vez por varios días después del día 28 para corregir esto - e –

1

También me enfrenté a la sa Me problema, en mi caso necesito para recuperar datos basado en un día específico en un mes, lo que se repite cada año .I utiliza 'FECHA' y consulta como este resultado

SELECT * FROM test_table WHERE MONTH(date) = 1 AND DAY(date) = 14

como esto

enter image description here

Advantage

  1. puedo utilizar las capacidades de MySQL.
  2. Disminuya los cálculos del lado del cliente.
  3. Puede utilizar date_field para otros cálculos

Mi sugerencia es utilizar esta forma

esto podría ser útil a alguien

Cuestiones relacionadas