Domanda

Qual è il modo migliore per archiviare un elenco collegato in un database mysql in modo che gli inserimenti siano semplici (ad es.non è necessario reindicizzare un sacco di cose ogni volta) e in modo tale che l'elenco possa essere facilmente estratto in ordine.

È stato utile?

Soluzione

Memorizza una colonna intera nella tabella chiamata "posizione".Registra uno 0 per il primo elemento dell'elenco, un 1 per il secondo elemento, ecc.Indicizza quella colonna nel tuo database e, quando vuoi estrarre i tuoi valori, ordina in base a quella colonna.

 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;

Per inserire un valore all'indice 3, modificare le posizioni delle righe 3 e successive, quindi inserire:

 update linked_list set position = position + 1 where position >= 3;
 insert into linked_list (my_value, position) values ("new value", 3); 

Altri suggerimenti

Utilizzando la soluzione di Adrian, ma invece di incrementare di 1, incrementare di 10 o addirittura 100.Quindi gli inserimenti possono essere calcolati alla metà della differenza di ciò che stai inserendo senza dover aggiornare tutto sotto l'inserimento.Scegli un numero abbastanza grande da gestire il numero medio di inserimenti: se è troppo piccolo, dovrai ricorrere all'aggiornamento di tutte le righe con una posizione più alta durante un inserimento.

creare una tabella con due colonne autoreferenziali PreviousID e NextID.Se l'elemento è il primo nell'elenco PreviousID sarà nullo, se è l'ultimo NextID sarà nullo.L'SQL sarà simile a questo:

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
}

Un elenco collegato può essere memorizzato utilizzando puntatori ricorsivi nella tabella.Si tratta più o meno delle stesse gerarchie archiviate in SQL e utilizza il modello di associazione ricorsiva.

Puoi saperne di più a riguardo Qui.

Spero che aiuti.

L'opzione più semplice sarebbe creare una tabella con una riga per elemento dell'elenco, una colonna per la posizione dell'elemento e colonne per gli altri dati nell'elemento.Quindi puoi utilizzare ORDER BY nella colonna della posizione per recuperare nell'ordine desiderato.

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 );

Per manipolare l'elenco è sufficiente aggiornare la posizione e quindi inserire/eliminare i record secondo necessità.Quindi per inserire un elemento nell'elenco 1 all'indice 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;

Poiché le operazioni sull'elenco possono richiedere più comandi (ad esempio, un inserimento richiederà un INSERT e un UPDATE), assicurati di eseguire sempre i comandi all'interno di una transazione.

Una variazione di questa semplice opzione consiste nell'incrementare la posizione di un fattore per ciascun elemento, ad esempio 100, in modo che quando si esegue un INSERT non sia sempre necessario rinumerare la posizione degli elementi successivi.Tuttavia, ciò richiede un piccolo sforzo in più per capire quando incrementare gli elementi successivi, quindi si perde semplicità ma si guadagna in prestazioni se si avranno molti inserimenti.

A seconda delle tue esigenze, potrebbero interessarti altre opzioni, come ad esempio:

  • Se desideri eseguire molte manipolazioni sull'elenco e non molti recuperi, potresti preferire avere una colonna ID che punta all'elemento successivo nell'elenco, invece di utilizzare una colonna di posizione.Quindi è necessaria una logica iterativa nel recupero dell'elenco per ottenere gli elementi in ordine.Questo può essere implementato in modo relativamente semplice in un processo memorizzato.

  • Se disponi di molti elenchi, un modo rapido per serializzare e deserializzare il tuo elenco in testo/binario e desideri archiviare e recuperare solo l'intero elenco, archivia l'intero elenco come un singolo valore in una singola colonna.Probabilmente non è quello che stai chiedendo qui però.

Questo post è vecchio ma darà comunque i miei 0,02$.Aggiornare ogni record in una tabella o in un set di record sembra una follia per risolvere l'ordine.anche la quantità di indicizzazione è pazzesca, ma sembra che la maggior parte l'abbia accettata.

La soluzione pazzesca che ho trovato per ridurre gli aggiornamenti e l'indicizzazione è creare due tabelle (e nella maggior parte dei casi d'uso non ordini comunque tutti i record in una sola tabella).Tabella A per contenere i record dell'elenco da ordinare e tabella B per raggruppare e conservare un record dell'ordine come stringa.la stringa dell'ordine rappresenta un array che può essere utilizzato per ordinare i record selezionati sul server Web o sul livello del browser di un'applicazione di pagina 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
}

Il formato della stringa dell'ordine dovrebbe essere id, posizione e un separatore per dividere() la stringa.nel caso dell'interfaccia utente jQuery la funzione .sortable('serialize') restituisce una stringa d'ordine compatibile con POST che include l'ID e la posizione di ciascun record nell'elenco.

La vera magia è il modo in cui scegli di riordinare l'elenco selezionato utilizzando la stringa di ordinamento salvata.questo dipenderà dall'applicazione che stai creando.ecco ancora un esempio da jQuery per riordinare l'elenco degli elementi: http://ovisdevelopment.com/oramincite/?p=155

https://dba.stackexchange.com/questions/46238/linked-list-in-sql-and-trees suggerisce un trucco per utilizzare la colonna di posizione a virgola mobile per inserimenti e ordinamenti rapidi.

Menziona anche SQL Server 2014 specializzato gerarchiaid caratteristica.

Ci sono alcuni approcci a cui mi vengono in mente subito, ciascuno con diversi livelli di complessità e flessibilità.Presumo che il tuo obiettivo sia preservare un ordine durante il recupero, piuttosto che richiedere l'archiviazione come un elenco collegato effettivo.

Il metodo più semplice sarebbe quello di assegnare un valore ordinale a ciascun record nella tabella (ad es.1, 2, 3, ...).Quindi, quando recuperi i record, specifica un ordine nella colonna ordinale per riportarli in ordine.

Questo approccio consente inoltre di recuperare i record indipendentemente dall'appartenenza a un elenco, ma consente l'appartenenza a un solo elenco e potrebbe richiedere una colonna aggiuntiva "ID elenco" per indicare a quale elenco appartiene il record.

Un approccio leggermente più elaborato, ma anche più flessibile, sarebbe quello di memorizzare le informazioni sull'appartenenza in uno o più elenchi in una tabella separata.La tabella avrebbe bisogno di 3 colonne:L'ID dell'elenco, il valore ordinale e un puntatore di chiave esterna al record di dati.Con questo approccio, i dati sottostanti non sanno nulla della loro appartenenza agli elenchi e possono essere facilmente inclusi in più elenchi.

Penso che sia molto più semplice aggiungere una colonna creata di Datetime tipo e una colonna di posizione di int, quindi ora puoi avere posizioni duplicate, nell'istruzione select usa il file order by posizione, opzione desc creata e l'elenco verrà recuperato in ordine.

Questo è qualcosa che sto cercando di capire da un po' anch'io.Il modo migliore che ho trovato finora è creare una singola tabella per l'elenco collegato utilizzando il seguente formato (questo è pseudo codice):

Lista collegata(

  • chiave1,
  • informazione,
  • chiave2

)

key1 è il punto di partenza.Key2 è una chiave esterna che si collega a se stessa nella colonna successiva.Quindi le tue colonne collegheranno qualcosa a qualcosa del genere

col1

  • chiave1 = 0,
  • informazioni = 'ciao'
  • chiave2 = 1

Key1 è la chiave primaria di col1.key2 è una chiave esterna che porta alla key1 di col2

col2

  • chiave1 = 1,
  • informazioni = 'come va'
  • chiave2 = nullo

key2 da col2 è impostato su null perché non punta a nulla

Quando inserisci per la prima volta una colonna nella tabella, dovrai assicurarti che key2 sia impostato su null altrimenti riceverai un errore.Dopo aver inserito la seconda colonna, puoi tornare indietro e impostare la chiave2 della prima colonna sulla chiave primaria della seconda colonna.

Questo è il metodo migliore per inserire più voci alla volta, quindi tornare indietro e impostare le chiavi esterne di conseguenza (o creare una GUI che lo faccia per te)

Ecco del codice effettivo che ho preparato (tutto il codice effettivo ha funzionato su MSSQL.Potresti voler fare qualche ricerca per la versione di SQL che stai utilizzando!):

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)

*Li ho inseriti in due file separati, perché deve essere fatto in due passaggi.MSSQL non ti consentirà di farlo in un solo passaggio, perché la tabella non esiste ancora a cui fare riferimento la chiave esterna.

L'elenco collegato è particolarmente potente in uno a molti relazioni.Quindi, se hai mai desiderato creare una serie di chiavi esterne?Bene, questo è un modo per farlo!Puoi creare una tabella primaria che punta alla prima colonna nella tabella dell'elenco collegato e quindi, invece del campo "informazioni", puoi utilizzare una chiave esterna per la tabella delle informazioni desiderata.

Esempio:

Diciamo che hai una burocrazia che mantiene i moduli.

Diciamo che hanno un tavolo chiamato schedario

Schedario(

  • ID armadio (conf.)
  • File ID (FK))

ogni colonna contiene una chiave primaria per il cabinet e una chiave esterna per i file.Questi file potrebbero essere moduli fiscali, documenti di assicurazione sanitaria, ricevute di autorizzazione per gite ecc

File(

  • ID file (pk)

  • ID file (fk)

  • ID file successivo (fk)

)

questo funge da contenitore per i file

File(

  • ID file (pk)

  • Informazioni sul fascicolo

)

questo è il file specifico

Potrebbero esserci modi migliori per farlo e ce ne sono, a seconda delle tue esigenze specifiche.L'esempio illustra solo il possibile utilizzo.

Un elenco può essere archiviato facendo in modo che una colonna contenga l'offset (posizione dell'indice dell'elenco): un inserimento al centro incrementa quindi tutto sopra il nuovo genitore e quindi esegue un inserimento.

Incrementa l''indice' SERIAL di 100, ma aggiungi manualmente i valori intermedi con un 'indice' uguale a Prev+Next / 2.Se mai saturi le 100 righe, riordina l'indice riportandolo a 100.

Ciò dovrebbe mantenere la sequenza con l'indice primario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top