¿Qué tipo de estructura de base de datos debo usar para que un sitio tenga una subcategoría infinita?

StackOverflow https://stackoverflow.com/questions/1418160

Pregunta

Por ejemplo, "Dole Banana" es un tipo de producto, aparece en la lista "Bananas" categoría, cuando abro el " Frutas " categoría, quiero ver "Dole Banana".

+ Food
|--+ Fruits
|------+ Bananas   
|------+ Apples
|--+ Vegetables
|------+ Onion
|------+ Spinach
¿Fue útil?

Solución

Normalmente he usado árboles de izquierda a derecha que están muy bien adaptados a las consultas de bases de datos. Tiene un valor parentId, izquierdo y derecho para cada nodo. Todos los nodos secundarios tienen un valor izquierdo / derecho que se encuentra entre los nodos principales izquierdo y derecho, lo que hace que sea muy fácil encontrar, por ejemplo, todos los secundarios / principales de un nodo. Proporciona una ligera sobrecarga en las inserciones, pero no debería ser un gran impacto a menos que inserte mucho.

Editar: solo una advertencia, sin embargo, debe realizar las operaciones de inserción / actualización en una transacción bloqueada o el árbol puede enredarse.

Otros consejos

Si está buscando recursos en línea que aborden este problema, "Almacenamiento de un árbol en una base de datos" sería una buena frase de búsqueda.

En cuanto a la solución, tenga en cuenta que cada subcategoría puede tener una o dos categorías principales. Por lo tanto, todo el árbol se puede almacenar en una sola tabla autorreferencial con un '' padre '' campo.

Usando su árbol de ejemplo:

 ID  | PARENT | NAME
-----+--------+-------------
  1  |  null  | Food
  2  |   1    | Fruits
  3  |   2    | Bananas
  4  |   2    | Apples
  5  |   1    | Vegetables
  6  |   5    | Onion
  7  |   5    | Spinach

Una tabla " Categorías " Con 3 campos.

  1. CategoryId no es nulo (clave principal)
  2. ParentCategoryId null
  3. CategoryName no es nulo

Para obtener todas las categorías raíz

select * from Categories where ParentCategoryId is null

Para obtener todas las subcategorías de alguna categoría específica:

select * from Categories where ParentCategoryId = 12

Puede usar una estructura de tabla simple con parent_category_id y recuperar todo el árbol con recursividad o implementar valores izquierda / derecha y recuperar todo el árbol utilizando el método transversal del árbol pedido previamente.

Si te refieres a un número infinito de niveles, entonces una tabla de autorreferencia que se puede recurrir. Ejemplo: StuffID, StuffName, StuffParentID (FK a Stuff ID)

Para un número finito, tablas fijas: padre-hijo-nieto

    CREATE TABLE [dbo].[Category](
    [CategoryId] [int] NOT NULL,
    [ParentCategoryId] [int] NULL,
    [CategoryName] [nvarchar](50) NOT NULL,
     CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
    (
        [CategoryId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON 

[PRIMARY]

GO

ALTER TABLE [dbo].[Category]  WITH CHECK ADD  CONSTRAINT [FK_Category_Category] FOREIGN KEY([ParentCategoryId])
REFERENCES [dbo].[Category] ([CategoryId])
GO

ALTER TABLE [dbo].[Category] CHECK CONSTRAINT [FK_Category_Category]
GO

Aquí hay un enfoque diferente que podría serle útil. Tiene un poco más de costos de mantenimiento que el enfoque PARENT_ID o lft / rght, pero la recuperación es mucho más fácil (y más rápida).

Las bananas Dole pueden estar en la mesa de productos. Tiene un solo category_id para un producto.

Teníamos el requisito de permitir múltiples categorías para un producto. Esto nos lleva a tener una tabla de unión de categorías_productos, donde el producto podría tener múltiples filas unidas. Luego, tuvimos que decidir si teníamos plátanos Dole solo en plátanos, o en plátanos y todos sus padres también. Como la velocidad de recuperación fue crítica, colocamos los plátanos dole en sus categorías y en todas sus categorías principales. Hay tres combinaciones de productos de categoría para los plátanos dole.

Usando esta estructura, devolver todos los elementos de cualquier categoría es fácil y rápido, solo una consulta. No puede hacer esto en el enfoque PARENT_ID (a menos que codifique a los padres, abuelos, etc.). Agregar una categoría es fácil. La categorización de un producto requiere la inserción de varias filas en la tabla de unión. Eliminar y mover categorías es un poco más complicado.

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