2009-07-06 13 views
8

Chcę zapisać listę numerów (Zasadniczo, set w kategoriach matematycznych) w relacyjnej bazie danych, w szczególności SQL Server 2005.Jak najlepiej przechowywać listę numerów w relacyjnej bazie danych?

Idealnie, chciałbym to być pojedyncza kolumna na danym stole ale chcę usłyszeć jakiekolwiek rozwiązanie. Dane, które muszę przechowywać, to, jak powiedziałem, zestaw liczb.

  • Nie jest wymagane, aby być sekwencyjna (tj luki są w porządku, normalne i typowe)
  • Zakresy są możliwe (czyli 1 - 4), ale jednocześnie chciałbym, aby wyświetlić ją w ten sposób, że” m dobrze z użyciem skrótów i innych do przechowywania go.
  • Może to być również "wszystko", więc przynajmniej jedna wartość musi być zarezerwowana, najlepiej logicznie, dla tego "nieskończonego" przypadku
  • Lista numerów nie musi być kolejność (tj. 3, 2, 9, 5), ale jest to korzystne i całkowicie uzasadnione, że będą one i mogą być sortowane przed wstawieniem, ponieważ tylko kod będzie wykonywał wstawianie, a nie użytkownicy ręczni. Mimo to prawdopodobnie nie powinien polegać na liście lub oczekiwać, że lista zostanie już posortowana.
  • Zbiór numerów muszą być łatwo przeszukiwania dla podzbioru (patrz poniżej)
  • Wszystkie liczby powinny odróżniać się (bez duplikaty), ale może i być wykonane przed wprowadzeniem

Kolumna rozumie do przechowywania wszystkich "numerów kroku" danego procesu, do którego odnosi się wiersz. Każdy wiersz może zatem dotyczyć jednego lub więcej kroków, w dowolnej kolejności, zakresie lub sekwencji. Maksymalna liczba możliwych kroków (zasadniczo zakres maksymalny) jest różna dla różnych rzędów, chociaż wątpię, aby którykolwiek z nich dostał się do setek, więc w 99,9% przypadków maksymalny czas nie powinien przekraczać 20 lub 30, a ja byłoby zaskoczeniem, gdyby kiedykolwiek dotarło do 100. Każdy wiersz ma co najmniej jedną wartość (krok) co najmniej (tzn. nie ma sensu mieć wiersza, który nie ma zastosowania do żadnego kroku), ale ja rysunek ten jest tak prosty jak ustawienie kolumny na not null.

Jednak jest przechowywany, chciałbym, aby można go było łatwo przeszukać. Na przykład wolałbym nie przeskakiwać przez wiele kółek, aby napisać zapytanie SQL, aby znaleźć na przykład wszystkie wiersze odnoszące się do "kroku 3". Jeśli dany wiersz składa się z kilku kroków (na przykład 2, 3, 7 i 8), nie powinno być zbyt trudno dopasować go podczas wyszukiwania w kroku 3.

Ponadto, chociaż chciałbym ma to jakiś logiczny sens, gdy patrzymy na surowe dane (dla każdego, kto potrzebuje pracy w systemie po tym, jak nie jestem w pobliżu, aby poprosić, a więc nie muszą czytać grubej dokumentacji, aby zrozumieć moje niejasne kodowanie), Jestem gotowy na kompromis w tej sprawie. Zakodowanie tej listy w coś, co można wiarygodnie zdekodować, jest zatem dopuszczalne.

Przepraszam, jeśli to jest duplikat. — Przeszukałem witrynę, ale podejrzewam, że ta kwestia cierpi na brak wiedzy o tym, czego szukać, jak ją sformułować lub zadzwonić, aby znaleźć to, czego szukam.

W komentarzu bardziej zastanawiam się, czy nie jest to jedna z tych dziedzin, w których relacyjne bazy danych są niewystarczające. Niestety, nie mam tutaj wyboru. Muszę przechowywać go w SQL Server. Zapisuję się osobno w pliku lub w innym trwałym zbiorze danych, obawiam się.

Odpowiedz

1

Zakończono przy użyciu solution to a similar question.

Mimo to dziękuję! Lubię czytać opinie wszystkich na temat ezoterycznych obszarów projektowania baz danych.

2

A dlaczego dodatkowe kroki w tabeli (processID JOIN, krok INT) nie są opcją? Jestem prawie pewny, że byłoby najłatwiejsze do utrzymania/kodowania.

SELECT process.name FROM process, steps WHERE process.id = steps.processID AND steps.step = 3; 

Pardon mój SQL, ale to było jakiś czas :)

EDIT: UNIQUE(processID, step) byłoby wskazane.

1

Użyłbym prostego i kanonicznego projektu relacyjnego: CREATE TABLE zakresy (process_id int, num_low int, num_hi int). Dwie ostatnie kolumny określają zakres. Niezależny indeks w każdej kolumnie. Dla "specjalnych" wartości nieskończoności wystarczy użyć maxints lub dodatkowych kolumn boolean.

Zalety: łatwe wyszukiwanie, czy konkretna liczba znajduje się w zasięgu, czy też zakresy się przecinają. Łatwa konserwacja. Ogólna zrozumiałość i prostota.

Wady: wymagana jest pewna logika podczas modyfikowania zestawu, tj. Sprawdzanie, czy nowo wstawiony lub zmodyfikowany zakres przecina się. Zakresy łączenia mogą być wymagane.

+0

Ale lista nie musi (i zazwyczaj nie jest) przyjemnego, prostego zakresu. Zwykle jest to jedna lub dwie, ewentualnie trzy różne liczby w żadnej określonej sekwencji (tj. 3, 5, 9). Tylko sporadycznie jest to 1 - 4. –

4

nie mogę zapamiętać poprawną terminologię dla tego, ale poprawny sposób to zrobić byłoby utworzyć tabelę jak ten poniżej:

| id | table1_id | value | 
-------------------------------- 
| 0 |   1 |  1 | 
| 1 |   1 |  2 | 
| 2 |   1 |  3 | 
| 3 |   1 |  7 | 
| 4 |   1 |  9 | 
| 5 |   2 |  1 | 
| 6 |   2 |  3 | 
| ... |  ... | ... | 

Dla każdej wartości w Tabela1 Państwo dodać do wymaganych wartości ten stół.

Dla "wszystkich" można utworzyć kolumnę w tabeli 1, która jest flagą, którą możesz ustawić, jeśli chcesz wszystko. (Używam "enum" w MySql, ale nie jestem pewien, czy to istnieje w SQL Server).

Nie jestem pewien, czy jest jakiś specyficzny sposób działania serwera SQL, ponieważ używam głównie MySql.

+0

Wspomniałem o platformie, ale szczerze mam nadzieję, że odpowiedź jest wystarczająco ogólna dla każdego rozsądnie wyposażonego systemu relacyjnej bazy danych. Wolałbym nie polegać na rozwiązaniu związanym z Microsoftem, ale jeśli JESTEŚ jakieś fajne sztuczki, to wszystko dla niego. Na przykład często używam Common Table Expressions i jestem prawie pewien, że są one specyficzną cechą SQL Server. –

1

Poniższa odpowiedź do zrobienia podtabeli (MitMaro) jest metodą "standardową".

JEŚLI MUSISZ umieścić zestaw liczb w jednej kolumnie lub tabeli, ale jedyny sposób, jaki mogę sobie wyobrazić, to użycie operacji bitowych do przechowywania zestawu i możesz użyć operacji bitowych w zapytaniach danych, aby wyszukać określone bity zestaw. Szybkie wyszukiwanie w Google wskazuje, że MSSql 2005 obsługuje to, ale tylko do 32-bitowej int, więc jeśli przejdziesz 32, napotkasz problemy.

Podsumowując, podtablica jest najbardziej standardowym rozwiązaniem dla bardziej zrozumiałych zapytań względem tabel (tabel). Jest to również najbezpieczniejsze wsparcie dla każdego przyszłego przypadku, w którym miałbyś więcej niż 32 mapy wartości.

1

Jeśli nie jesteś przywiązany do SQL Server, PostgreSQL ma świetne wsparcie dla tego typu rzeczy poprzez array. Mają nawet specjalną wartość dla nieskończoności.

Jeśli jesteś przywiązany do serwera SQL, sposób MitMaro jest najlepszy.

+0

Interesujące, że to ma. Chciałem czegoś takiego jak typ danych "tablica". Ale tak, muszę używać tego, co mamy - SQL Server. :) –

1
create table setmember (setid int, setmemberid int) 
create unique nonclustered index idx_setmember_idx1 on setmember (setid, setmemberid) 

Pozwolę sobie założyć magiczną liczbę (-1 lub 999999999) dla "wszystkich".

Będzie to wysoce wydajne zarówno w przypadku wysyłania zapytań w zestawie, jak i aktualizacji wstawiania za pośrednictwem indeksu nieklastrowanego. Unikalność wymusza nie powtarzanie wpisów. Problematyczne jest wymuszanie albo "wszystkich", albo wielu członków zestawu jako ograniczenia, ale zmniejszają się zyski, chociaż można to zrobić w wyzwalaczu.

Dodatkowo dodać

create nonclustered index idx_setmember_idx2 on setmember (setmemberid, setid) 

aby umożliwić efektywne kwerend wyszukiwania wstecznego.

Jeśli używasz typów tablic, możesz nie być w stanie wdrożyć wydajnego wyszukiwania wstecznego.

Uwaga: wszystkie powyższe SQL są zgodne z ANSI.

Powiązane problemy