2009-05-29 17 views
7

Estoy haciendo un sitio web de videos donde las categorías estarán anidadas:¿Cómo creo categorías anidadas en una base de datos?

p. Programación-> Lenguaje C -> MIT Videos -> Video 1 Programación -> Lenguaje C -> Stanford Video -> Video 1 Programación -> Python -> Video 1

Estas categorías y subcategorías será creado por usuarios sobre la marcha. Tendré que mostrarlos a medida que las personas los creen en forma de un menú navegable, para que las personas puedan explorar la colección fácilmente.

¿Podría alguien ayudarme con cómo puedo crear una base de datos así?

+0

¿duplicado? http://stackoverflow.com/questions/317322/optimized-sql-for-tree-structures –

+0

https://stackoverflow.com/questions/17081951/my-sql-multiple-category-subcategory-subcategory – Calvin

Respuesta

7

Quassnoi dijo:

que puedes usar cualquiera conjuntos anidados o modelos padre-hijo.

Solía ​​implementar ambos. Lo que podría decir es:

Use la arquitectura del conjunto anidado si su tabla de categorías no cambia a menudo, porque en una cláusula de selección es rápido y con una sola solicitud puede obtener toda la rama de la jerarquía para una entrada determinada . Pero en una cláusula de inserción o actualización, lleva más tiempo que un modelo hijo principal actualizar los campos izquierdo y derecho (o inferior y superior en el ejemplo a continuación).

Otro punto, bastante trivial, debo admitir, pero:
Es muy difícil cambiar la jerarquía con la mano directamente en la base de datos (Podría ocurrir durante el desarrollo). Por lo tanto, asegúrese de aplicar primero una interfaz para jugar con el conjunto anidado (cambiando nodo padre, mover un nodo rama, la eliminación de un nodo o toda la sucursal, etc.)

Aquí hay dos artículos sobre el tema:

última cosa, yo no lo probamos, pero he leído en alguna parte que se puede hav e más de un árbol en una tabla de conjuntos anidados, me refiero a varias raíces.

3

Debe utilizar los modelos nested sets o parent-child.

Parent-child:

 
typeid parent name 

1  0  Buyers 
2  0  Sellers 
3  0  Referee 
4  1  Electrical 
5  1  Mechanic 
SELECT * 
FROM mytable 
WHERE group IN 
     (
     SELECT typeid 
     FROM group_types 
     START WITH 
       typeid = 1 
     CONNECT BY 
       parent = PRIOR typeid 
     ) 

seleccionará todos los compradores en Oracle.

Nested sets:

 
typeid lower upper Name 
1  1  2  Buyers 
2  3  3  Sellers 
3  4  4  Referee 
4  1  1  Electrical 
5  2  2  Mechanic 
SELECT * 
FROM group_types 
JOIN mytable 
ON  group BETWEEN lower AND upper 
WHERE typeid = 1 

seleccionará todos los compradores en cualquier base de datos.

Consulte this answer para obtener más información.

Nested sets es más fácil de consultar, pero es más difícil de actualizar y más difícil de construir una estructura de árbol.

11

hacer una tabla de categorías con los siguientes campos:

  • CategoryID - Integer
  • CategoryName - Cadena/Varchar/Cualquiera que sea
  • ParentID - Integer

Su ParentID será después hacer referencia a la espalda a la CategoryID de su padre.

Ejemplo:

CategoryID CategoryName ParentID 
--------------------------------- 
1   Dog   NULL 
2   Cat   NULL 
3   Poodle  1 
4   Dachsund  1 
5   Persian  2 
6   Toy Poodle 3 
+0

¿Cómo construyo? una consulta para crear la navegación desde dicha tabla? hay una manera fácil? – MathOldTimer

+0

Jake: no sé cómo haría su propia navegación, pero la forma estándar sería mostrar un solo nivel (como el nivel superior) primero con una consulta como "seleccionar * de tblCategories donde ParentID es NULL", por lo que obtendrías Dog and Cat. Luego, cuando haces clic en un perro, puedes obtener el siguiente nivel preguntando "Seleccionar * desde tblCategories donde ParentID = 1" porque 1 es la categoría de Perro. Y luego continúas de la misma manera cuanto más abajo perforas. – TheTXI

+0

Gracias! ¡Esto fue útil! – MathOldTimer

0

Lo que necesita es una relación padre-hijo básica:

Category (ID: int, ParentID: nullable int, Name: nvarchar(1000)) 
5

A partir del ejemplo en su pregunta que parece que te gustaría que fuera posible para una dada categoría para tener múltiples padres (por ej., "Videos MIT -> Programación Video 1" así como "Video -> Programación Video 1"), en cuyo caso simplemente agregar una columna ParentID no sería suficiente.

Recomendaría crear dos tablas: una tabla simple de Categorías con columnas CategoryID y CategoryName, y una tabla CategoryRelationships separada con las columnas ParentCategoryID y ChildCategoryID. De esta forma puede especificar tantas relaciones padre-hijo como desee para cualquier categoría en particular. Incluso sería posible usar este modelo para tener una relación dual en la que dos categorías son mutuamente padre e hijo simultáneamente.(. De la parte superior de mi cabeza, no puedo pensar en un gran uso para este escenario, pero al menos se ilustra la flexibilidad del modelo es)

+0

¡Gracias! Esto es exactamente lo que yo quería. Como ejemplo, me gustaría que se incluyera un "video de iniciador del lenguaje de ensamblaje" tanto en "conceptos básicos de ingeniería inversa" como en "lenguajes de programación". – MathOldTimer

0

Una mejor manera de almacenar el parent_id de la mesa es tenerlo anidado dentro del ID por ejemplo

100000 Programación 110000 Lenguaje C 111000 Video 1 Programación 111100 Lenguaje C 111110 Stanford vídeo

etc..so todo lo que necesita es una secuencia de comandos para procesar la ID de manera que el primer dígito representa la categoría de nivel superior y así sucesivamente a medida que profundiza en la jerarquía

+0

Esta es una forma bastante interesante. ¿Tiene alguna idea de cómo consultar tales datos? –

+0

¿Esto no lo limita a 10 artículos de nivel superior 0-9?¿Cuál es la razón para usar los ceros, está usando un número determinado de enteros que limita la cantidad de hijos posibles? ¿Cómo insertarías nuevos elementos y los actualizarías? –

Cuestiones relacionadas