Pregunta

Una aplicación web que estoy trabajando ha encontrado un 'bug' inesperada -. La base de datos de la aplicación tiene dos tablas (entre muchos otros) se llama 'Unidos' y 'ciudades'

Unidos 'campos de la tabla:

-------------------------------------------
idStates   |   State   |   Lat   |   Long
-------------------------------------------

' idStates ' es una clave principal de incremento automático.

Ciudades 'campos de la tabla:

----------------------------------------------------------
idAreaCode   |   idStates   |   City   |   Lat   |   Long
----------------------------------------------------------

' idAreaCode ' es una clave principal que consta de código de país + código de área (por ejemplo 91422, donde 91 es el código de país para la India y 422 es el código de área de una ciudad en la India). ' idStates ' es una clave externa derivada de ' Unidos ' mesa para asociar cada ciudad en el ' Ciudades ' mesa con su correspondiente Estado.

Nos dimos cuenta de que el código del país + código de área combinación serían únicos para cada ciudad, y por lo tanto de manera segura podría ser utilizado como una clave principal. Todo estaba funcionando. Pero un lugar en la India encontró un 'defecto' inesperado en el diseño db - la India, al igual que los EE.UU. es una democracia federal y se divide geográficamente en muchos estados o territorios de la unión. Tanto los datos de los estados y territorios de la unión se almacena en el ' Unidos ' mesa. Hay, sin embargo, una ubicación - Chandigarh - el cual pertenece a dos estados ( Haryana y Buenos Aires ) y es también un territorio de la unión por sí misma.

Obviamente, el diseño db actual no nos permiten almacenar más de un registro de la ciudad ' Chandigarh '.

Una de las soluciones propuestas es la creación de una clave principal que combina las columnas ' idAreaCode ' y ' idStates .

Me gustaría saber si esta es la mejor solución posible?

. (FYI: estamos usando MySQL con el motor InnoDB)


Más información:

  • La base de datos almacena información meteorológica para cada ciudad. Por lo tanto, el estado y la ciudad son el punto de partida de cada consulta.
  • Nuevos datos para cada ciudad se insertan todos los días usando un archivo CSV. El archivo CSV incluye una idStates (por estado) y idAreaCode (por ciudad) la columna que se utiliza para identificar cada registro.
  • normalización de base de datos es importante para nosotros.

Nota: La razón para no usar un auto incrementar clave principal de la tabla de la ciudad es que la base de datos se actualiza cada día / hora mediante un archivo CSV (que se genera por otra aplicación). Y cada registro en el archivo CSV es identificado por la columna de la idStates y idAreaCode. Por lo tanto, se prefiere que la clave principal que se utiliza en la tabla de la ciudad es el mismo para todas las ciudades, aunque se borre la mesa y se actualiza de nuevo. códigos postales (o códigos PIN) y los códigos de área (o códigos STD) cumplen con los criterios de ser única, estática (no cambie a menudo) y una lista preparada de estos son fácilmente disponibles. (Nos decidimos por códigos de área, por ahora, porque la India está en el proceso de actualizar sus códigos PIN a un nuevo formato).

  

La solución nos decidimos por era de manejar esto a nivel de aplicación en lugar de hacer cambios en el diseño de bases de datos. En la base de datos sólo se va a almacenar un registro de 'Chandigarh'. En la aplicación que hemos creado una bandera para cualquier búsqueda de 'Chandigarh, Punjab' o 'Chandigarh, Haryana' para redirigir búsqueda a este registro. Sí, no es ideal, pero un compromiso aceptable ya que esta es la única excepción que hemos encontrado hasta ahora.

¿Fue útil?

Solución

Parece que se están reuniendo datos para una guía telefónica. ¿Es usted? ¿Por qué son importantes para que los estados? La respuesta a esta pregunta probablemente determinará que el diseño de base de datos que funciona mejor para usted.

Usted puede pensar que es obvio lo que es una ciudad. No es. Depende de lo que se va a hacer con los datos. En los EE.UU., hay esta unidad llamada MSA (área estadística metropolitana). El Kansas City MSA abarca tanto Kansas City, Kansas y Kansas City, Missouri. Si la unidad de MSA tiene sentido o no depende del uso previsto de los datos. Si ha utilizado códigos de área en los Estados Unidos para determinar las ciudades, que terminarías con una agrupación muy diferente de MSA. Una vez más, depende de lo que se va a hacer con los datos.

En general cada vez que los patrones jerárquicos de las subdivisiones políticas se rompen, la solución más general es considerar la relación de muchos a muchos. A resolver este problema de la misma manera a resolver otros problemas de muchos a muchos. Al crear una nueva tabla, con dos claves externas. En este caso las claves externas son IdAreacode y IdStates.

Ahora usted puede tener uno arecode en muchos estados y un estado que abarca muchos códigos de área. Es una pena que accpet esta sobrecarga adicional para cubrir sólo una excepción. ¿Sabe si la excepción que han descubierto es sólo la punta del iceberg, y hay muchas de esas excepciones?

Otros consejos

Tener una clave compuesta podría ser problemático cuando se quiere hacer referencia a esa tabla, ya que el cuadro que hace referencia tendría que tener todas las columnas de la clave principal tiene.

Si ese es el caso, es posible que desee tener una clave de secuencia primaria, y tienen la idAreaCode y idStates definidos en un grupo NOT NULL UNIQUE.

Creo que lo mejor es añadir otra mesa, países. Su problema es un ejemplo por qué la normalización de bases de datos es importante. No se puede simplemente mezclar y combinar diferentes claves para una columna.

Por lo tanto, le sugiero que para crear estas tablas:

países:

+------------+--------------+
| country_id | country_name |
+------------+--------------+

estados:

+------------+----------+------------+
| country_id | state_id | state_name |
+------------+----------+------------+

ciudades

+------------+----------+---------+-----------+
| country_id | state_id | city_id | city_name |
+------------+----------+---------+-----------+

datos

+------------+----------+---------+---------+----------+
| country_id | state_id | city_id | data_id | your_CSV |
+------------+----------+---------+---------+----------+

Los campos en negrita son las claves principales. Introduzca un country_id estándar como 1 para los Estados Unidos, 91 de la India, y así sucesivamente. city_id también debe usar su ID de serie.

A continuación, puede encontrar cualquier cosa pertenece a sí bastante rápido con un mínimo de gastos. Todos los datos se pueden introducir directamente a la tabla de datos, por lo que sirve como un punto de entrada, el almacenamiento de todos los datos en una sola mancha. No sé con MySQL, pero si su partición de soporte de base de datos, que puede particionar las tablas de datos de acuerdo a country_id o country_id + state_id a un par de conjuntos de servidores, por lo que también acelerará el rendimiento de su base de datos considerablemente. La primera, segunda y tercera tabla no tomará mucho golpear la carga del servidor en absoluto, y sólo sirven como referencia. Va a trabajar principalmente en la cuarta tabla de datos. Puede añadir datos tanto como desee, sin duplicar nunca más.

Si sólo tiene uno de datos por ciudad, se puede omitir la tabla de datos y pasar a la mesa CSV_data ciudades como esto:

ciudades

+------------+----------+---------+-----------+----------+
| country_id | state_id | city_id | city_name | CSV_data |
+------------+----------+---------+-----------+----------+

Si vas con la adición de una columna adicional a la clave de modo que usted puede agregar un registro adicional para una ciudad determinada, entonces usted no está normalizando adecuadamente sus datos. Dado que ahora se ha descubierto que una ciudad puede ser miembro de múltiples estados, sugeriría la eliminación de cualquier referencia a un estado de la tabla de las ciudades, a continuación, añadir una tabla StateCity que le permite relacionar los estados a las ciudades (la creación de la mañana: m relación).

Imtroduce una clave sustituta. ¿Qué vas a hacer cuando cambian los códigos de área numbets o separarnos? El uso de claves de negocio como clave principal casi siempre es un error.

Su resumen anterior es otro ejemplo de por qué.

  

"Nos dimos cuenta de que el código del país + código de área combinación serían únicos para cada ciudad, y por lo tanto de manera segura podría ser utilizado como una clave principal"

Después de haber leído esto, dejé de leer nada más en este tema. ¿Cómo puede alguien imaginar que de esta manera?
códigos de área, por definición (el primero que encontré en Internet):
  -. "Un código de área es el número de prefijo que se utilizan para identificar una región geográfica en base al Plan serie norteamericana Este número de 3 dígitos se puede asignar a cualquier número en América del Norte, incluyendo Canadá, Estados Unidos, México, América Latina y el Caribe"[1]

Dejando a un lado que son cambiables y definida sólo en América del Norte, los códigos de área no son de 3 dígitos en algunos otros países (de 3 dígitos es simplemente no tener suficiente cientos de miles de ubicaciones en algunos países. Por cierto, el área de mi madre código tiene 5 dígitos) y que no están estrictamente vinculada a lugares geográficos fijos.

Los códigos de área han migración lugares como los campos de la deriva del Ártico con hielo, tribus Normadic, la migración de las unidades militares o, incluso, grandes buques oceánicos, etc.

Entonces, ¿qué pasa con la fusión de algunas ciudades en uno (o viceversa)?

[1] | http://www.successfuloffice.com/articles/answering-service -Glosario-área-code.htm

Te recomiendo añadir un nuevo campo de clave principal de la tabla de las ciudades que será simplemente auto-incrementales. La metodología de KISS (mantenerlo simple).

Cualquier otra solución es engorroso y confuso en mi opinión.

  1. La base de datos no está normalizado. Puede ser en parte normalizada. Va a encontrar muchos más errores y limitaciones en la extensibilidad, como consecuencia de ello.

  2. Una jerarquía de país, entonces a continuación Estado City está muy bien. Usted no necesita una tabla adicional de muchos a muchos como algunos sugieren. La dicha ciudad (y muchos en América) se multiplican en tres Estados.

  3. Al colocar countryCode y AreaCode, concatenado, en una sola columna, que ha roto las reglas básicas de bases de datos, por no mencionar el código añadido en cada acceso. Además, countryCode no está normalizado.

  4. El problema es que del país + Código de área es una mala elección para una llave para una ciudad. En términos reales, tiene muy poco que ver con una ciudad, se aplica a grandes extensiones de tierra. Si el significado de la ciudad fue cambiado a la ciudad (como en, su empresa se inicia la recolección de datos para las grandes ciudades), el PP se rompería por completo.

  5. Mago tiene la única respuesta que está cerca de ser correcta, eso te salvará de sus limitaciones actuales, debido a la falta de normalización. No es preciso decir que la respuesta del mago se normaliza; es correcta elección de los identificadores, que forman una jerarquía en este caso. Pero me quito las columnas "ID", ya que son innecesarias, 100% columnas redundantes, 100% índices redundantes. Los char () columnas están bien como están, y está bien para el (claves compuestas) PK. Recuerde que usted necesita un índice en el char () la columna de todos modos, para garantizar que es único.

    • Si tuviera esto, la estructura relacional, con identificadores de relación, su problema no existiría.
    • y sus pobres los usuarios no tienen que resolver las cosas tontas a cabo o mantener un registro de los identificadores sin sentido. Acaban de estado, naturalmente : State.Name, City.Name, ReadingType, datos ... .
  6. Al llegar al extremo inferior de la jerarquía (Ciudad), el compuesto de PK se ha convertido onerosa (3 x CHAR (20)), y no me gustaría llevar en la tabla de datos (esp si hay importaciones diarias CSV y muchas lecturas o filas por la ciudad). Por lo tanto para la ciudad solamente, me gustaría añadir una clave sustituta, como el PK.

  7. Sin embargo, para el DDL publicado, así como lo fue, sin normalizar el PP y el uso de identificadores relacionales, sí, la FC de la ciudad es incorrecta. Debería ser (idStates, idAreaCode), y no al revés. Eso va a arreglar el problema.

Muy mala denominación por cierto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top