Como armazenar uma lista em uma coluna de uma tabela de banco de dados
Então, por a resposta do Mehrdad a uma pergunta relacionada, EU Obter que uma coluna de tabela de bases de dados" próprias " não armazena uma lista. Em vez disso, você deve criar outra tabela que efetivamente mantém os elementos da referida lista e, em seguida, ligar-se a ela diretamente ou através de uma tabela de junção. No entanto, o tipo de lista que eu quero criar será composto por itens únicos (ao contrário do exemplo da pergunta ligada fruit). Além disso, os itens da minha lista estão explicitamente ordenados-que significa que se guardasse os elementos noutra mesa, teria de os classificar sempre que os acedesse. Finalmente, a lista é basicamente atômica em que sempre que Eu desejo acessar a lista, Eu quero acessar a lista inteira em vez de apenas um pedaço dela - então parece tolo ter que emitir uma consulta de banco de dados para reunir pedaços da lista.
a solução do AKX (ligada acima) é serializar a lista e armazená-la numa coluna binária. Mas isso também parece inconveniente porque significa que tenho de me preocupar com a serialização e a deseralização.
Há alguma solução melhor? Se não existe uma solução melhor, então porquê? Parece que este problema deve surgir de vez em quando.... só um pouco mais de informação para te dizer de onde venho. Assim que eu tinha acabado de começar a entender SQL e bases de dados em geral, eu estava ligado ao LINQ para SQL, e então agora eu estou um pouco mimado, porque eu espero lidar com o meu modelo de objeto de programação sem ter que pensar sobre como os objetos são pesquisados ou armazenados na base de dados.
Obrigado A Todos!John
Atualização: assim, na primeira onda de respostas que estou recebendo, eu vejo "você pode ir pela rota CSV/XML... mas não!". Agora estou à procura de explicações sobre o porquê. Aponta-me algumas boas referências.
também, para lhe dar uma ideia melhor do que estou a fazer: na minha base de dados tenho uma tabela de funções que terá uma lista de pares (x,y). (O quadro terá também outras informação que não é relevante para a nossa discussão.) Eu nunca precisarei ver parte da lista de pares (x,y). Em vez disso, vou pegar em todos eles e colocá-los no ecrã. Eu vou permitir que o usuário arraste os nós ao redor para mudar os valores ocasionalmente ou adicionar mais valores para o gráfico.
10 answers
Correndo o risco de simplificar demasiado as coisas, a normalização da base de dados é o processo de definir a sua base de dados com base no que os dados são, para que possa escrever consultas sensatas e consistentes contra ela e ser capaz de mantê-la facilmente. A normalização é projetada para limitar inconsistências lógicas e corrupção em seus dados, e há um monte de níveis para ele. taxa o artigo sobre a normalização da base de Dados é muito bom.
Basicamente, a primeira regra (ou forma) de normalização afirma que a sua tabela deve representar uma relação. Isto significa que:
- você deve ser capaz de diferenciar uma linha de qualquer outra linha (em outras palavras, a sua tabela deve ter algo que Pode servir como uma chave primária. Isto também significa que nenhuma linha deve ser duplicada.
- qualquer ordenação dos dados deve ser definida pelos dados, não por a ordenação física das linhas (SQL é baseada na idéia de um conjunto, o que significa que a Somente ordenando que você deve confiar é o que você define explicitamente em sua consulta)
- cada intersecção linha / coluna deve conter um e apenas um Valor
A tua lista pode ser completamente "atómica" agora, e isso pode não mudar para este projecto. Mas você vai, no entanto, entrar no hábito de fazer coisas semelhantes em outros projetos, e você eventualmente (provavelmente rapidamente) vai encontrar um cenário onde você agora está encaixando sua abordagem rápida-n-Fácil de lista-em-uma-coluna, onde é totalmente inapropriado. Não há muito trabalho adicional na criação da tabela correta para o que você está tentando armazenar, e você não será ridicularizado por outros desenvolvedores SQL quando eles vêem o seu projeto de banco de dados. Além disso, o LINQ para o SQL vai ver a sua relação e dar-lhe a interface adequada orientada a objectos para a sua lista automaticamente. Por que você desistiria da conveniência oferecida pelo ORM para que você possa executar hackery de banco de dados não-padrão e mal aconselhado?
O que eu vi muitas pessoas fazerem é isto (pode não ser a melhor abordagem, corrija-me se estiver errado):
A tabela que estou a usar no exemplo é dada abaixo(a tabela inclui alcunhas que você deu às suas namoradas específicas. Cada namorada tem um id único):
nicknames(id,seq_no,names)
Suponho que queiras guardar muitas alcunhas com uma identificação. É por isso que incluímos um campo seq_no
.
Agora, preencha estes valores para a sua tabela:
(1,1,'sweetheart'), (1,2,'pumpkin'), (2,1,'cutie'), (2,2,'cherry pie')
Se quiseres encontrar todos os nomes que você deu à sua amiga id 1 então você pode usar:
select names from nicknames where id = 1;
Se ainda quiser seguir esta via de serialização da lista, poderá considerar guardar a lista em XML. Alguns bancos de dados, como o SQL Server, ainda têm um tipo de dados XML. A única razão pela qual sugiro XML é que quase por definição, esta lista tem de ser curta. Se a lista é longa, então serializá-la em geral é uma abordagem horrível. Se você for pela rota CSV, você precisa ter em conta os valores que contêm o delimitador, o que significa que você é obrigado a usar identificadores citados. Persistindo que as listas são curtas, provavelmente não fará muita diferença se você usar CSV ou XML.
Se precisar de consultar na lista, guarde-a numa tabela.
Se quiser sempre a lista, pode guardá-la como uma lista delimitada numa coluna. Mesmo neste caso, a menos que você tenha razões muito específicas para não, armazená-lo em uma tabela de pesquisa.
Eu apenas o armazenaria como CSV, se são valores simples, então deve ser tudo o que você precisa (XML é muito descritivo e serializando de/para ele provavelmente seria exagerado, mas isso seria uma opção também).
Aqui está uma boa resposta para como tirar os CSVs com o LINQ.Aqui está o design' tradicional ' DB:
List(ListID, ListName)
Item(ItemID,ItemName)
List_Item(ListID, ItemID, SortOrder)
Aqui está a tabela des-normalizada:
Lists(ListID, ListContent)
A ideia aqui-você mantém a tabela listas usando gatilhos ou código de Aplicação. Sempre que modificar o conteúdo do List_Item, apropriado as linhas nas listas são actualizadas automaticamente. Se leres a maioria das listas, pode funcionar muito bem. Profissionais - você pode ler listas em uma declaração. Contras-atualizações levam mais tempo e esforços.
Se você realmente quisesse armazená-lo em uma coluna e tê-lo questionável, muitos bancos de dados suportam XML agora. Se não perguntar, você pode armazená-los como valores separados por vírgulas e analisá-los com uma função quando você precisa deles separados. Concordo com todos os outros, no entanto, se você está olhando para usar uma base de dados relacional uma grande parte da normalização é a separação de dados assim. Não estou a dizer que todos os dados se encaixem numa base de dados relacional. Você pode sempre olhar para outros tipos de bases de dados se muitos dos seus dados não se encaixam no modelo.
Eu acho que, em certos casos, você pode criar um FALSO "lista" de itens no banco de dados, por exemplo, a mercadoria tem algumas fotos para mostrar seus detalhes, você pode concatenar todas as Identificações de imagens divididas por vírgula e armazenar a seqüência de caracteres para o banco de dados, então você só precisa analisar a seqüência de caracteres quando você precisar dele. Estou trabalhando em um site agora e estou planejando usar desta forma.
Resposta simples: se, e apenas se, tiver a certeza de que a lista será sempre usada como lista, então junte-se à lista no seu fim com um carácter (como '\0') que não será usado no texto nunca, e guarde isso. Depois, quando o recuperar, poderá dividir por '\ 0'. Há, naturalmente, outras maneiras de ir sobre este material, mas esses são dependentes de seu fornecedor de banco de dados específico.
Como exemplo, você pode armazenar JSON em uma base de dados Postgres. Se a sua lista é texto, e você só quero a lista sem mais problemas, é um compromisso razoável.
Outros se aventuraram em sugestões de serialização, mas eu realmente não acho que serialização é uma boa idéia: parte da coisa legal sobre bases de dados é que vários programas escritos em diferentes linguagens podem falar uns com os outros. E programas serializados usando o formato Java não fariam muito bem se um programa Lisp quisesse carregá-lo. Se queres uma boa maneira de fazer este tipo de coisas, normalmente há tipos de array-or-similar disponíveis. Postgres, por exemplo, oferece matriz como um tipo, e permite que você armazenar uma matriz de texto, se é isso que você quer, e há truques similares para MySql e MS SQL usando JSON, e IBM DB2 oferecem um tipo de matriz, bem como (em suas próprias útil documentação). Isto não seria tão comum se não houvesse necessidade disto. O que se perde ao ir por aquela estrada é a noção da lista como um monte de coisas em sequência. Pelo menos nominalmente, as bases de dados tratam os campos como valores únicos. Mas se é só isso que queres, então devias ir em frente. É um julgamento de valor que tens de fazer por ti.