Mam kilka baz danych utworzonych za pomocą Entity Framework Code First; aplikacje działają i ogólnie jestem całkiem zadowolony z tego, co pozwala mi Code First. Najpierw jestem programistą, a po drugie DBA. Czytam o DataAttributes, aby dalej opisać w C #, co chcę, aby baza danych zrobiła; a moje pytanie brzmi: jaką karę będę jadł, mając te nvarchar(max)
łańcuchy na stole (patrz przykład poniżej)?
W tej konkretnej tabeli znajduje się kilka kolumn; w języku C # są one zdefiniowane jako takie:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public string Source { get; set; }
public DateTime Generated { get; set; }
public DateTime Written { get; set; }
Oczekuję zapytania i / lub sortowania na podstawie nazwy, źródła, wygenerowanego i zapisanego. Oczekuję, że Nazwa i Źródło będą miały długość 0-50 znaków, czasami nawet do 150. Spodziewam się, że ta tabela zacznie być dość mała (<100 tys. Rzędów), ale z czasem znacznie wzrośnie (> 1m wierszy). Oczywiście wiadomość może być mała lub duża i prawdopodobnie nie będzie się o nią pytać.
Chcę wiedzieć, czy w mojej kolumnie Nazwa i Źródło zdefiniowano trafienie wydajnościowe, nvarchar(max)
gdy nigdy nie oczekuję, że będą miały więcej niż 150 znaków?
[MaxLength]
lub[StringLength]
atrybuty. Niektóre dodatkowe możliwe negatywne czynniki zbyt szerokich kolumn są wymienione w odpowiedzi @ PaulWhite tutajvarchar(max)
wszędzie szkodzi Twojej wydajności - nie rób tego! Używaj odpowiednich typów danych - używajvarchar(max)
TYLKO, jeśli NAPRAWDĘ potrzebujesz więcej niż 8000 znaków! (Nigdy nie widziałem, aby imię i adres e-mail osoby były tak długie!) - Zobacz, jaki jest sens używania VARCHAR (n)? po więcej informacjiOdpowiedzi:
Większe elementy danych nvarchar (maksymalnie) (ponad 8000 bajtów) zostaną przeniesione do pamięci tekstowej i będą wymagały dodatkowych operacji we / wy. Mniejsze przedmioty będą przechowywane w rzędzie. Istnieją opcje kontrolujące to zachowanie - więcej informacji można znaleźć w tym artykule MSDN .
Jeśli są przechowywane w rzędzie, nie ma znaczącego obciążenia wydajności we / wy; przetwarzanie danych może wiązać się z dodatkowym obciążeniem procesora, ale może to być niewielkie.
Jednak pozostawienie kolumn nvarchar (max) leżących wokół bazy danych, gdzie nie są one potrzebne, jest raczej kiepską formą. Ma pewien narzut wydajności i często rozmiary danych są bardzo pomocne w zrozumieniu tabeli danych - na przykład kolumna varchar o szerokości 50 lub 100 znaków może być opisem lub polem tekstowym, w którym (powiedzmy) 10- 20 znaków może być kodem. Zdziwiłbyś się, jak duże znaczenie ma to na podstawie bazy danych przy takich założeniach.
Praca w hurtowni danych, tak często, jak w słabo obsługiwanych lub udokumentowanych starszych systemach, posiadanie łatwego do zrozumienia schematu bazy danych jest dość cenna. Jeśli uważasz, że baza danych jest dziedzictwem aplikacji, postaraj się być miły dla osób, które odziedziczą ją po tobie.
źródło
Chociaż to nie odpowiada na konkretne pytanie, może to uniemożliwić zadanie pytania: Możliwe jest ustawienie długości zmiennych łańcuchowych w klasie modelu C #, co spowoduje, że Entity Framework wygeneruje SQL, który używa typu nvarchar o stałej długości (np.
nvarchar(50)
) zamiastnvarchar(max)
.Na przykład zamiast:
Możesz użyć:
Możesz również wymusić, aby typ był
varchar
zamiastnvarchar
, w razie potrzeby, w następujący sposób:Źródło: https://stackoverflow.com/questions/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920
źródło
varchar(50)
), ale EF 6 wymaga tego, co jest w tej odpowiedzi.Indeksowanie największego problemu. Z BOL:
Jeśli nie możesz poprawnie indeksować, będziesz mieć wolne zapytania. A z punktu widzenia integralności danych
nvarchar(max)
pozwolenie na umieszczenie większej ilości złych danych w polu niż określenie limitu byłoby.źródło
Tak, domyślne zachowanie EF w odwzorowaniu
string
nanvarchar(max)
nie jest dobre. W EF 6 możesz dodać własną niestandardową konwencję, aby zastąpić to zachowanie własnym preferowanym domyślnym odwzorowaniem.Przesłonięcie
OnModelCreating
jak wyżej spowoduje zmianę domyślnego odwzorowania dla wszystkich łańcuchów navarchar(200)
.źródło
the default EF behavior in mapping string to nvarchar(max) is not good
to wydaje się być twoją ogólną opinią. możesz wyjaśnić, dlaczego to nie jest dobre? A może uważasz, że EF nie jest strukturą dla aplikacji biznesowych, w których musisz pracować z wieloma językami? Ponieważ jest to pożądany typ kolumny do obsługi wielu języków w bazie danych.max
jest okropne. Ale jeśli chcesz obsługiwać wiele języków (i ich różne zestawy znaków), musisz ich użyć,nvarchar
czy się mylę?