Próbuję zrozumieć najlepszy sposób, aby zdecydować, jak duże powinny być kolumny varchar, zarówno z punktu widzenia przechowywania, jak i wydajności.
Wydajność Wydaje się
, że z moich badańtego varchara (maks.) należy używać tylko wtedy, gdy naprawdę go potrzebujesz; to znaczy, jeśli kolumna musi pomieścić więcej niż 8000 znaków, jednym z powodów jest brak indeksowania (chociaż jestem trochę podejrzliwy co do indeksowania pól varchar w ogóle. Jestem jednak całkiem nowy w zasadach DB, więc może to nieuzasadnione ) i kompresja (bardziej dotyczy przechowywania). W rzeczywistości ludzie wydają się zalecać używanie tylko tego, czego potrzebujesz, podczas wykonywania varchar (n) .... przewymiarowanie jest złe, ponieważ zapytania muszą uwzględniać maksymalny możliwy rozmiar. Ale stwierdzono również, że silnik wykorzysta połowę wskazanego rozmiaru jako oszacowanie średniego rzeczywistego rozmiaru danych. Oznaczałoby to, że należy określić na podstawie danych, jaki jest średni rozmiar, podwoić go i użyć jako n. Jednak w przypadku danych o bardzo niskiej, ale niezerowej zmienności, oznacza to do 2x przewymiarowania ponad maksymalny rozmiar, co wydaje się dużo, ale może nie jest? Docenione będą mile widziane.
Przechowywanie
Po przeczytaniu o tym, jak działa przechowywanie w rzędzie a poza rzędem, i pamiętając, że faktyczne przechowywanie jest ograniczone do rzeczywistych danych, wydaje mi się, że wybór n ma niewielki lub żaden wpływ na przechowywanie (poza upewniając się, że jest wystarczająco duży, aby pomieścić wszystko). Nawet użycie varchar (max) nie powinno mieć żadnego wpływu na przechowywanie. Zamiast tego celem może być ograniczenie rzeczywistego rozmiaru każdego wiersza danych do ~ 8000 bajtów, jeśli to możliwe. Czy to dokładny odczyt rzeczy?
Kontekst
Niektóre z danych naszych klientów nieco się wahają, dlatego generalnie poszerzamy kolumny nieco, niż powinny być, powiedzmy, 15-20% większe, dla tych kolumn. Zastanawiałem się, czy są jakieś inne szczególne względy; na przykład ktoś, z kim pracuję, powiedział mi, żebym używał rozmiarów 2 ^ n - 1 (nie znalazłem dowodów, że coś takiego jest ....)
Mówię o początkowym tworzeniu tabeli. Klient powie nam, że zacznie przesyłać nam nową tabelę i wyśle przykładowe dane (lub tylko pierwszy zestaw danych produkcyjnych), na które spojrzymy i utworzy tabelę na naszym końcu, aby przechowywać dane. Chcemy, aby nasza tabela obsługiwała przyszły import, a także to, co jest w próbie. Ale niektóre rzędy muszą się wydłużyć, więc je wypełniamy.
Pytanie brzmi, ile i czy istnieją wytyczne techniczne?
źródło
Odpowiedzi:
Bez względu na konkretny typ danych musisz mieć możliwość przechowywania dowolnych żądań aplikacji, które mają być przechowywane. Nie możesz określić czegoś mniejszego niż maksymalny rozmiar tego, co faktycznie zostanie zapisane.
Nie musisz też, ani nie chcesz, określać długości kolumny większej niż maksymalny rzeczywisty rozmiar, który będzie przechowywany z różnych powodów: przydział pamięci zapytania, potencjalnie wypełnienie maksymalnego rozmiaru wiersza i nie pozostawianie miejsca na dodanie kolumn w przyszłość itp.
Prawda, łańcuch o zmiennej długości i kolumny binarne nie mają wpływu na pamięć, jaki mają typy danych o stałej długości (ciąg / binarny / numeryczny / data / itp.) (Chociaż niektóre z tych implikacji można unieważnić przez kompresję danych lub użycie
SPARSE
definicji kolumny opcja). Jednak, jak wskazałeś, nawet jeśli nie ma to bezpośredniego wpływu na pamięć, nadal istnieje wpływ na wydajność zawyżania wymaganej pamięci dla zapytań.Bądź rozsądny. Używać tylko tego, czego potrzebujesz. Można rozważyć, czy istnieje duże prawdopodobieństwo, że długość kolumny będzie musiała wzrosnąć w najbliższej przyszłości, ale należy pamiętać, że łatwiej jest powiększyć rozmiar kolumny niż zmniejszyć jej rozmiar. Tak, część pracy będzie wymagała zaangażowania, ale ponieważ praca ta jest jedynie „potencjalna”, podczas gdy implikacje nadmiernego rozmiaru są „rzeczywiste”, często najlepiej jest zdefiniować kolumny w oparciu o to, czego naprawdę potrzebujesz, a nie to, co być może -sorta myśli, że możesz potrzebować w przyszłości. Wiele omawianych zmian nigdy się nie zdarza i często nie można przewidzieć wymaganych zmian. Idź z tym, co wiesz.
Nie jestem do końca pewien, o co tu chodzi. SQL Server fizycznie ograniczy Cię do nieco ponad 8000 bajtów. Używanie typów LOB -
VARCHAR(MAX)
,NVARCHAR(MAX)
,VARBINARY(MAX)
,XML
, i przestarzałeTEXT
,NTEXT
iIMAGE
typy - umożliwiają wykraczając poza tym ograniczenie początkowego rozmiaru strony, ale to tylko ze względu na umieszczenie wskaźnika (16 lub więcej bajtów, w zależności od rodzaju, oraz w zależności od rozmiar wartości przechowywanej poza wierszem podczas używaniaMAX
typów). Rzeczywisty fizyczny limit strony danych nie zmienił się.Twoim celem powinno być wykorzystanie jak najmniejszej ilości fizycznej przestrzeni do przechowywania tego, co aplikacja / firma potrzebuje do przechowywania, bez przerywania lub obcinania, tak aby niekompletna wartość straciła znaczenie lub spowodowała problemy na dalszych etapach. Jeśli potrzebujesz przechowywać 12 000 znaków, użyj
VARCHAR(MAX)
tego, ponieważ jest to potrzebne. Jeśli przechowujesz numer telefonu lub kod pocztowy / pocztowy, korzystanie z niego byłoby nierozsądneVARCHAR(100)
i nieodpowiedzialneVARCHAR(MAX)
.Czy wszystkie systemy nie mają przynajmniej niektórych danych, które się zmieniają? Każdy system, który przechowuje nazwisko osoby, byłby kwalifikowany, prawda? Istnieje dość duża zmienność długości nazw. A potem masz kogoś takiego jak Prince, który zmienia nazwę na symbol, a teraz masz zupełnie inny problem, który nie jest długością. Tak właśnie jest.
Ale, aby przez chwilę grać w adwokata diabła: w jaki sposób wartość „15-20% większa niż to, co jest potrzebne”, może nie być faktycznie potrzebną wartością? Powiedzmy, że toczy się dyskusja na temat dodawania nowej kolumny, a ktoś sugeruje 50 znaków, a następnie ktoś inny mówi: „cóż, 20% więcej to 60, więc zróbmy 60, ponieważ ktoś może mieć 60”. Jeśli prawdą jest, że klient może mieć 60 lat, wówczas 60 jest i zawsze było rzeczywistą potrzebną wartością, a 50 było błędem przez cały czas.
Oczywiście pomogłoby to, gdyby istniały jakieś wskazówki co do źródła danych, ponieważ:
VARCHAR
i dostajesz skargi, że psuje znaki Unicode, które są teraz dozwolone w nazwach domen, to musiało tak byćNVARCHAR
), aleProductSKU
lepiej być na tyle duży, aby zmieścił się w nich wszystkich jednostek SKU klienta.Robisz tutaj wiele założeń. Pewnie niektóre pola mogą się powiększyć. Ale z drugiej strony mogą nie. Lub niektóre mogą się zmniejszyć. Niektórzy mogą zmienić się z nie-Unicode na Unicode (gdy zdadzą sobie sprawę, że świat się zmniejsza i nie można zakładać, że nazwiska będą miały tylko podstawowe znaki ASCII / US English). Lub mogą przestać wysyłać pole. Lub mogą dodać jedno lub więcej pól w przyszłości. Dowolna kombinacja tego i innych rzeczy. Dlaczego więc skupiać się tylko na
VARCHAR
kolumnach? Co zrobić, jeśli obecnie wysyłająINT
wartość i za rok lub dwa osiągają maksymalną wartość i zaczynają wysyłaćBIGINT
? Co jeśli mają pole „status” o wartościach 0–5. Po prostu zakładaszINT
który jest „wyściełany”, ponieważ pozwala na wzrost, ale prawdopodobnie powinien byćTINYINT
?Jedyną rzeczą, którą możesz bezpiecznie przewidzieć, jest to, że próba przewidzenia, jak zmienią się dane Twoich klientów, będzie błędna częściej niż poprawna. A bycie poprawnym to kwestia szczęścia / zbiegów okoliczności (jeśli nie szczęście, to po prostu idź zagrać na loterii;).
Tak więc wytyczna jest następująca:
Masz już przykładowe dane, świetnie. Nie zapominaj jednak, że masz również dane kontaktowe klienta: telefon i / lub e-mail. Skontaktować się z nimi! Zapytaj ich o specyfikację danych (tak jak twój system, dane aktualnie w ich systemie mogą mieć maksymalną długość 35, ale w ich systemie jest to zdefiniowane jako
VARCHAR(50)
, a ich system zaakceptuje do tej długości, w takim przypadku powinieneś użyć 50). Zapytaj ich, czy mają jakieś krótkoterminowe plany zmiany oraz o te typy danych (typ i / lub rozmiar).źródło
varchar(255)
avarchar(256)
dla dalszych rozważań