Estou tentando entender como armazenar corretamente as informações solicitadas em um banco de dados relacional.
Um exemplo:
Digamos que eu tenha uma lista de reprodução, composta por músicas. Dentro do meu banco de dados relacional, tenho uma tabela Playlists
contendo alguns metadados (nome, criador, etc.). Eu também tenho uma tabela chamada Songs
, contendo informações sobre a playlist_id
música e também sobre a música (nome, artista, duração etc.).
Por padrão, quando uma nova música é adicionada a uma lista de reprodução, ela é anexada ao final. Ao fazer o pedido no ID da música (crescente), a ordem será a ordem de adição. Mas e se um usuário conseguir reordenar músicas na lista de reprodução?
Eu vim com algumas idéias, cada uma com suas vantagens e desvantagens:
- Uma coluna chamada
order
, que é um número inteiro . Quando uma música é movida, a ordem de todas as músicas entre a antiga e a nova posição é alterada, para refletir a alteração. A desvantagem disso é que muitas consultas precisam ser feitas toda vez que uma música é movida, e o algoritmo de movimentação não é tão trivial quanto nas outras opções. - Uma coluna chamada
order
, que é um decimal (NUMERIC
). Quando uma música é movida, é atribuído o valor do ponto flutuante entre os dois números adjacentes. Desvantagem: os campos decimais ocupam mais espaço e pode ser possível ficar sem precisão, a menos que seja tomado o cuidado de redistribuir o intervalo após algumas alterações. - Outra maneira seria ter
previous
umnext
campo e que faça referência a outras músicas. (ou são NULL no caso da primeira e da última música da lista de reprodução no momento; basicamente, você cria uma lista vinculada ). Desvantagem: consultas como 'encontrar a décima música na lista' não são mais de tempo constante, mas sim de tempo linear.
Qual desses procedimentos é mais frequentemente usado na prática? Qual desses procedimentos é mais rápido em bancos de dados de médio a grande porte? Existem outras maneiras de arquivar isso?
EDIT: Por uma questão de simplicidade, no exemplo, uma música pertence apenas a uma lista de reprodução (um relacionamento muitos-para-um). Obviamente, também é possível usar uma Junction Table para que a lista de músicas seja uma relação de muitos para muitos (e aplique uma das estratégias acima nessa tabela).
update songorder set order = order - 1 where order >= 12 & order <= 42; update songorder set order = 42 where id = 123;
- são duas atualizações - não trinta. Três, se você quiser colocar uma restrição exclusiva em ordem.
Queries like 'find the Xth Song in the list' are no longer constant-time
também é válido para a opção 2.