una - Lista enlazada en SQL
tabla sql server (12)
¿Cuál es la mejor manera de almacenar una lista enlazada en una base de datos mysql para que las inserciones sean simples (es decir, no tenga que reindexar muchas cosas cada vez) y de modo que la lista pueda retirarse fácilmente en orden?
Almacene una columna entera en su tabla llamada ''posición''. Registre un 0 para el primer elemento en su lista, un 1 para el segundo elemento, etc. Indique esa columna en su base de datos, y cuando desee extraer sus valores, ordene por esa columna.
alter table linked_list add column position integer not null default 0;
alter table linked_list add index position_index (position);
select * from linked_list order by position;
Para insertar un valor en el índice 3, modifique las posiciones de las filas 3 y superiores, y luego inserte:
update linked_list set position = position + 1 where position >= 3;
insert into linked_list (my_value, position) values ("new value", 3);
Creo que es mucho más simple agregar una columna creada de tipo Datetime
y una columna de posición de int
, por lo que ahora puede tener posiciones duplicadas, en la instrucción select usar el order by
posición, la opción desc creada y su lista se buscará en orden.
Esta publicación es antigua pero todavía dará mi .02 $. Actualizar cada registro en una tabla o un conjunto de registros suena loco para resolver el orden. la cantidad de indexación también es una locura, pero parece que la mayoría lo ha aceptado.
La solución loca que ideé para reducir las actualizaciones y la indexación es crear dos tablas (y en la mayoría de los casos de uso, no ordena todos los registros en una sola tabla). La Tabla A para mantener los registros de la lista ordenada y la Tabla B para agrupar y contener un registro del pedido como una cadena. la cadena de orden representa una matriz que se puede usar para ordenar los registros seleccionados en el servidor web o en la capa de navegador de una aplicación de página web.
Create Table A{
Id int primary key identity(1,1),
Data varchar(10) not null
B_Id int
}
Create Table B{
Id int primary key Identity(1,1),
GroupName varchat(10) not null,
Order varchar(max) null
}
El formato de la picadura de la orden debe ser id, posición y algún separador para dividir () su cadena por. en el caso de jQuery UI, la función .sortable (''serialize'') genera una cadena de órdenes para usted que es POST amigable que incluye la identificación y la posición de cada registro en la lista.
La verdadera magia es la forma en que eliges reordenar la lista seleccionada usando la cadena de orden guardada. esto dependerá de la aplicación que esté construyendo. Aquí hay un ejemplo de jQuery para reordenar la lista de artículos: http://ovisdevelopment.com/oramincite/?p=155
Esto es algo que he tratado de resolver por un tiempo yo mismo. La mejor forma que he encontrado hasta ahora es crear una sola tabla para la lista vinculada usando el siguiente formato (esto es un pseudo código):
Lista enlazada(
- key1,
- información,
- key2
)
key1 es el punto de partida. Key2 es una clave externa que se vincula a sí misma en la columna siguiente. Entonces tus columnas enlazarán algo que enlazará algo como esto
col1
- key1 = 0,
- información = ''hola''
- key2 = 1
Key1 es la clave principal de col1. key2 es una clave externa que conduce a la clave 1 de col2
col2
- key1 = 1,
- información = ''wassup''
- key2 = nulo
key2 de col2 se establece en nulo porque no apunta a nada
Cuando ingresa por primera vez una columna en la tabla, deberá asegurarse de que la clave 2 esté configurada como nula o de que se obtenga un error. Después de ingresar la segunda columna, puede regresar y establecer la clave 2 de la primera columna en la clave principal de la segunda columna.
Este es el mejor método para ingresar muchas entradas a la vez, luego retroceder y configurar las claves foráneas en consecuencia (o crear una GUI que solo lo haga por usted)
Aquí hay un código real que preparé (todo el código real funcionó en MSSQL. ¡Quizás desee investigar un poco sobre la versión de SQL que está utilizando!):
createtable.sql
create table linkedlist00 (
key1 int primary key not null identity(1,1),
info varchar(10),
key2 int
)
register_foreign_key.sql
alter table dbo.linkedlist00
add foreign key (key2) references dbo.linkedlist00(key1)
* Los puse en dos archivos separados, porque tiene que hacerse en dos pasos. MSSQL no le permitirá hacerlo en un solo paso, porque la tabla aún no existe para la referencia de la clave externa.
La Lista enlazada es especialmente poderosa en relaciones de uno a muchos . Entonces, si alguna vez quiso crear una serie de claves externas? ¡Bueno, esta es una forma de hacerlo! Puede crear una tabla principal que apunte a la primera columna de la tabla de lista vinculada, y luego, en lugar del campo "información", puede usar una clave externa para la tabla de información deseada.
Ejemplo:
Digamos que tienes una Burocracia que guarda formularios.
Digamos que tienen una tabla llamada archivador
Archivador(
- ID del gabinete (pk)
- ID de archivos (fk))
cada columna contiene una clave principal para el gabinete y una clave externa para los archivos. Estos archivos pueden ser formularios de impuestos, documentos de seguro médico, permisos de viaje de campo, etc.
Archivos (
ID de archivos (pk)
ID de archivo (fk)
Siguiente ID de archivo (fk)
)
esto sirve como un contenedor para los archivos
Archivo(
ID de archivo (pk)
Información en el archivo
)
este es el archivo específico
Puede haber mejores formas de hacer esto y las hay, dependiendo de sus necesidades específicas. El ejemplo solo ilustra el uso posible.
Hay algunos enfoques que puedo pensar de inmediato, cada uno con diferentes niveles de complejidad y flexibilidad. Supongo que su objetivo es preservar un pedido en la recuperación, en lugar de requerir almacenamiento como una lista vinculada real.
El método más simple sería asignar un valor ordinal a cada registro en la tabla (por ejemplo, 1, 2, 3, ...). Luego, cuando recupere los registros, especifique un orden en la columna ordinal para volverlos a ordenar.
Este enfoque también le permite recuperar los registros sin tener en cuenta la membresía en una lista, pero permite la membresía en una sola lista, y puede requerir una columna de "identificador de lista" adicional para indicar a qué lista pertenece el registro.
Un enfoque un poco más elaborado pero también más flexible sería almacenar información sobre la membresía en una lista o listas en una tabla separada. La tabla necesitaría 3 columnas: la id de la lista, el valor ordinal y un puntero de clave externa para el registro de datos. Bajo este enfoque, los datos subyacentes no saben nada acerca de su membresía en listas, y pueden incluirse fácilmente en listas múltiples.
Incremente el ''índice'' de SERIE por 100, pero agregue manualmente los valores intermedios con un ''índice'' igual a Prev + Siguiente / 2. Si alguna vez satura las 100 filas, vuelva a ordenar el índice a 100s.
Esto debería mantener la secuencia con índice primario.
La opción más simple sería crear una tabla con una fila por elemento de lista, una columna para la posición del artículo y columnas para otros datos en el artículo. Luego puede usar ORDER BY en la columna de posición para recuperar en el orden deseado.
create table linked_list
( list_id integer not null
, position integer not null
, data varchar(100) not null
);
alter table linked_list add primary key ( list_id, position );
Para manipular la lista simplemente actualice la posición y luego inserte / elimine registros según sea necesario. Entonces, para insertar un elemento en la lista 1 en el índice 3:
begin transaction;
update linked_list set position = position + 1 where position >= 3 and list_id = 1;
insert into linked_list (list_id, position, data)
values (1, 3, "some data");
commit;
Dado que las operaciones en la lista pueden requerir múltiples comandos (por ejemplo, una inserción requerirá un INSERTAR y una ACTUALIZACIÓN), asegúrese de realizar siempre los comandos dentro de una transacción.
Una variación de esta opción simple es aumentar la posición por algún factor para cada elemento, digamos 100, de modo que cuando realiza un INSERT no siempre necesite volver a numerar la posición de los siguientes elementos. Sin embargo, esto requiere un poco más de esfuerzo para calcular cuándo incrementar los siguientes elementos, por lo que pierde simplicidad pero obtiene rendimiento si tiene muchos insertos.
Dependiendo de sus requisitos, otras opciones pueden ser atractivas, como:
Si desea realizar muchas manipulaciones en la lista y no muchas recuperaciones, puede preferir tener una columna de ID apuntando al siguiente elemento de la lista, en lugar de usar una columna de posición. Entonces necesita lógica iterativa en la recuperación de la lista para poder ordenar los elementos. Esto se puede implementar de manera relativamente fácil en un proceso almacenado.
Si tiene muchas listas, una forma rápida de serializar y deserializar su lista a texto / binario, y solo desea almacenar y recuperar toda la lista, entonces almacene toda la lista como un valor único en una sola columna. Sin embargo, probablemente no es lo que estás pidiendo aquí.
Se puede almacenar una lista haciendo que una columna contenga el desplazamiento (posición del índice de la lista): una inserción en el centro se incrementa luego sobre el nuevo padre y luego se inserta.
Una lista vinculada se puede almacenar usando punteros recursivos en la tabla. Esto es muy similar a las jerarquías que se almacenan en Sql y esto está utilizando el patrón de asociación recursivo.
Puedes aprender más sobre esto here .
Espero que esto ayude.
Usar la solución de Adrian, pero en lugar de incrementarla en 1, incrementarla en 10 o incluso 100. Luego, las inserciones se pueden calcular a la mitad de la diferencia de lo que está insertando sin tener que actualizar todo lo que está debajo de la inserción. Elija un número lo suficientemente grande como para manejar su número promedio de inserciones; si es demasiado pequeño, tendrá que volver a actualizar todas las filas con una posición más alta durante una inserción.
cree una tabla con dos columnas autoreferenciadas ID anterior y SiguienteID. Si el elemento es lo primero en la lista, ID anterior será nulo; si es el último, NextID será nulo. El SQL se verá algo así:
create table tblDummy
{
PKColumn int not null,
PreviousID int null,
DataColumn1 varchar(50) not null,
DataColumn2 varchar(50) not null,
DataColumn3 varchar(50) not null,
DataColumn4 varchar(50) not null,
DataColumn5 varchar(50) not null,
DataColumn6 varchar(50) not null,
DataColumn7 varchar(50) not null,
NextID int null
}
https://dba.stackexchange.com/questions/46238/linked-list-in-sql-and-trees sugiere un truco para usar la columna de posición de coma flotante para inserciones y pedidos rápidos.
También menciona la característica especializada hierarchyid SQL Server 2014.