database - software - Almacenamiento de horario comercial en una base de datos
database design software (5)
Actualmente estoy tratando de encontrar la mejor manera de almacenar las horas de operación de una empresa en una base de datos.
Por ejemplo:
El negocio A tiene las siguientes horas de operación
- Lunes: 9 a.m. - 5 p.m.
- Martes: 9 a.m. - 5 p.m.
- Miércoles: 9 a.m. - 5 p.m.
- Jueves: 9 a.m. - 5 p.m.
- Viernes: de 9 a.m. a 5 p.m.
- Sábados: de 9 a.m. a 12 del mediodía
- Domingo: cerrado
Actualmente tengo un modelo de datos similar al siguiente
CREATE TABLE "business_hours" (
"id" integer NOT NULL PRIMARY KEY,
"day" varchar(16) NOT NULL,
"open_time" time,
"close_time" time
)
donde el "día" está restringido a una elección de los 7 días de la semana en el código (a través del ORM). Para probar si una empresa está cerrada en un día determinado, comprueba si open_time y close_time son NULL. Está relacionado con el negocio a través de una tabla intermedia (relación de muchos a muchos).
¿Alguien tiene alguna sugerencia para este esquema de base de datos? Algo sobre eso no me parece correcto.
Aprendí que si desea que el marcado de datos de Google reconozca sus datos, debe seguir estas pautas:
https://schema.org/openingHours
http://schema.org/OpeningHoursSpecification Contiene "fechas válidas", que es muy útil para algunas empresas.
https://schema.org/docs/search_results.html#q=hours
Debería estar bien sin una clave principal, a menos que esté permitiendo que las empresas compartan las mismas horas con la tabla de unirse; curiosamente eventualmente tendría una cantidad finita de combinaciones; No estoy seguro de cuántos serían: p
Con uno de mis proyectos utilicé las columnas:
[uInt] business_id, [uTinyInt] día, [char (11)] timeRange
Si desea admitir OpeningHoursSpecification, deberá agregar validFrom y validThrough.
El rango de tiempo tiene el siguiente formato: hh: mm-hh: mm
Aquí hay una función que lo analiza, también puede modificar esta función para analizar solo un abrir / cerrar, si los mantiene como columnas separadas en el DB.
Según mi experiencia, recomendaría que permitiera varias veces al día, permitir una forma de saber si están cerradas explícitamente ese día, o abiertas las 24 horas o las 24 horas, los 7 días de la semana. Le dije a la mía que si faltaba un día en la base de datos, el negocio estaba cerrado ese día.
/**
* parseTimeRange
* parses a time range in the form of
* ''08:55-22:00''
* @param $timeRange ''hh:mm-hh:mm'' ''08:55-22:00''
* @return mixed [''hourStart''=>, ''minuteStart''=>, ''hourEnd''=>, ''minuteEnd''=>]
*/
function parseTimeRange($timeRange)
{
// no validating just parsing
preg_match(''/(?P<hourStart>/d{1,2}):(?P<minuteStart>/d{2})-(?P<hourEnd>/d{1,2}):(?P<minuteEnd>/d{2})/'', $timeRange, $matches);
return $matches;
}
Depende de lo que necesita almacenar y cómo podrían ser los datos del mundo real.
Si necesita poder determinar si la empresa está abierta en cierto punto, puede ser un poco incómodo consultar el esquema según lo establecido. Más importante aún, sin embargo, es: ¿Alguna vez necesitarías atender un cierre a mediodía?
Algunas opciones incluyen;
- Un esquema como el que tienes, pero con la opción de tener múltiples períodos para el mismo día. Sería conveniente para la pausa del almuerzo, pero sería incómodo para ejecutar una consulta que le da los horarios de apertura para un día determinado, por ejemplo, para la presentación a un usuario.
- Un enfoque de estilo de mapa de bits; "000000000111111110000000" para 9-5. La desventaja de este enfoque es que debe elegir una granularidad específica, es decir, horas completas o medias horas o, de hecho, minutos. Cuanto más fina sea la granularidad, más difícil será leer los datos para un humano. Puede usar operadores bit a bit para almacenar este valor como un solo número en lugar de una cadena de enteros, pero nuevamente daña la legibilidad.
En general, no veo nada de malo en esto. Excepto...
Almacenaba el día de la semana como un entero usando cualquier sistema de numeración que use su lenguaje de programación nativo (en sus bibliotecas). Esto disminuirá el tamaño de la base de datos y eliminará las comparaciones de cadenas de su código.
Probablemente coloque la clave externa en la tabla de negocios aquí en esta tabla. De esa forma no necesitarás una tabla de enlaces.
Así que supongo que haría:
CREATE TABLE "business_hours" (
"id" integer NOT NULL PRIMARY KEY,
"business_id" integer NOT NULL FOREIGN KEY REFERENCES "businesses",
"day" integer NOT NULL,
"open_time" time,
"close_time" time
)
En mi lógica comercial, impondré una restricción de que cada "negocio" tiene al menos 7 "horas hábiles". ( Al menos porque Jon Skeet tiene razón, es posible que desee horas de vacaciones.) Aunque es posible que desee relajar esta limitación simplemente dejando de "horas hábiles" durante los días que el negocio está cerrado.
Podría pensar en factorizar las vacaciones al incluir campos adicionales para el mes del año / día del mes / semana del mes. La semana del mes tiene algunas pequeñas subtítulos "último" podría ser, por ejemplo, la semana 4 o 5, dependiendo del año.
Una situación que no está cubierta por este esquema es varios períodos de apertura en un día. Por ejemplo, el pub local está abierto de 12:00 a 14:30 y de 17:00 a 23:00.
Tal vez una taquilla de teatro está abierta para una matinée y una función de noche.
En ese momento, debe decidir si puede tener varias entradas para el mismo día o si necesita representar horas diferentes en la misma fila.
¿Qué hay de los horarios de apertura que cruzan la medianoche? Digamos que un bar está abierto de 19:00 a 02:00. No podría simplemente comparar los horarios de apertura y cierre con el tiempo que desea probar.