tło
Jestem studentem pierwszego roku CS i pracuję w niepełnym wymiarze godzin dla małej firmy mojego taty. Nie mam doświadczenia w tworzeniu aplikacji w świecie rzeczywistym. Pisałem skrypty w Pythonie, trochę zajęć w C, ale nic takiego.
Mój tata ma małą firmę szkoleniową i obecnie wszystkie zajęcia są planowane, rejestrowane i monitorowane za pośrednictwem zewnętrznej aplikacji internetowej. Istnieje funkcja eksportu / „raportów”, ale jest bardzo ogólna i potrzebujemy konkretnych raportów. Nie mamy dostępu do faktycznej bazy danych w celu uruchomienia zapytań. Poproszono mnie o skonfigurowanie niestandardowego systemu raportowania.
Moim pomysłem jest tworzenie ogólnych eksportów CSV i importowanie ich (prawdopodobnie za pomocą Pythona) do bazy danych MySQL hostowanej w biurze każdej nocy, skąd mogę uruchamiać potrzebne zapytania. Nie mam doświadczenia w bazach danych, ale rozumiem podstawy. Przeczytałem trochę o tworzeniu baz danych i normalnych formularzach.
Wkrótce możemy zacząć mieć międzynarodowych klientów, więc chcę, aby baza danych nie eksplodowała, jeśli / kiedy tak się stanie. Obecnie mamy również kilka dużych korporacji jako klientów, z różnymi oddziałami (np. Spółka macierzysta ACME, oddział opieki zdrowotnej ACME, oddział opieki nad ACME)
Wymyślony przeze mnie schemat jest następujący:
- Z perspektywy klienta:
- Klienci to główny stół
- Klienci są powiązani z działem, w którym pracują
- Działy mogą być rozrzucone po całym kraju: HR w Londynie, marketing w Swansea itp.
- Działy są powiązane z działem firmy
- Podziały są powiązane ze spółką dominującą
- Z perspektywy klas:
- Sesje to główny stół
- Nauczyciel jest powiązany z każdą sesją
- Statusid jest nadawany każdej sesji. Np. 0 - zakończone, 1 - anulowane
- Sesje są pogrupowane w „paczki” o dowolnym rozmiarze
- Każda paczka jest przypisana do klienta
- Sesje to główny stół
„Zaprojektowałem” (bardziej jak bazgroły) schemat na kawałku papieru, starając się go znormalizować do trzeciej postaci. Następnie podłączyłem go do MySQL Workbench i sprawiło, że wszystko było dla mnie ładne:
( Kliknij tutaj, aby wyświetlić grafikę w pełnym rozmiarze )
(źródło: maian.org )
Przykładowe zapytania, które będę uruchamiał
- Którzy klienci, którzy nadal mają kredyt, są nieaktywni (klienci bez zajęć zaplanowanych w przyszłości)
- Jaki jest wskaźnik frekwencji na klienta / dział / oddział (mierzony identyfikatorem statusu w każdej sesji)
- Ile zajęć miał nauczyciel w ciągu miesiąca
- Zgłoś klientów, którzy mają niski wskaźnik frekwencji
- Raporty niestandardowe dla działów HR ze wskaźnikami obecności osób w ich dziale
Pytania)
- Czy to jest inżynieria, czy kieruję się w dobrym kierunku?
- Czy potrzeba łączenia wielu tabel w przypadku większości zapytań spowoduje duży spadek wydajności?
- Dodałem do klientów kolumnę „ostatnia sesja”, ponieważ prawdopodobnie będzie to typowe zapytanie. Czy to dobry pomysł, czy powinienem ściśle znormalizować bazę danych?
Dziękuję za Twój czas
źródło
divisions
ma nazwę kolumnydivisionid
. Nie uważasz tego za zbędne? Po prostu to nazwijid
. także nazwy twoich tabel, w tym_has_
: usunę to i po prostu nadam jej nazwęcities_departments
. TwojeDATETIME
kolumny powinny być typuTIMESTAMP
, chyba że są wartości wejściowe użytkownika. Myślę, że dobrym pomysłem jest mieć tabelecities
icountries
. możesz mieć problemy z ograniczeniem tabel do jednegostatus
. rozważ skorzystanie z niegoINT
i dokonaj na nim porównań bitowych - abyś mógł zachować tam więcej znaczeniaOdpowiedzi:
Więcej odpowiedzi na twoje pytania:
1) Jesteś właściwie celem kogoś, kto po raz pierwszy zbliża się do takiego problemu. Wydaje mi się, że wskazówki od innych w tej kwestii do tej pory w dużej mierze to pokrywają. Dobra robota!
2 i 3) Osiągnięty wynik wydajności będzie w dużej mierze zależał od posiadania i optymalizacji odpowiednich indeksów dla poszczególnych zapytań / procedur, a co ważniejsze, liczby rekordów. O ile nie mówisz o ponad milionie rekordów w swoich głównych tabelach, wydajesz się być na dobrej drodze do zaprojektowania wystarczająco głównego nurtu, aby wydajność nie była problemem na rozsądnym sprzęcie.
To powiedziawszy, a to odnosi się do twojego pytania 3, z początkiem, który masz, prawdopodobnie nie powinieneś zbytnio martwić się wydajnością lub nadwrażliwością na normalizację ortodoksyjną. Jest to serwer raportowania, który budujesz, a nie zaplecze aplikacji oparte na transakcjach, które miałoby znacznie inny profil pod względem znaczenia wydajności lub normalizacji. Baza danych stanowiąca kopię zapasową aplikacji do rejestracji i planowania na żywo musi zwracać uwagę na zapytania, które zwracają dane po kilku sekundach. Nie tylko funkcja serwera raportów ma większą tolerancję na złożone i długie zapytania, ale strategie poprawy wydajności są bardzo różne.
Na przykład w środowisku aplikacji opartym na transakcjach opcje poprawy wydajności mogą obejmować refaktoryzację procedur przechowywanych i struktur tabel do n-tego stopnia lub opracowanie strategii buforowania dla małych ilości często żądanych danych. W środowisku raportowania z pewnością możesz to zrobić, ale możesz mieć jeszcze większy wpływ na wydajność, wprowadzając mechanizm migawki, w którym zaplanowany proces działa i przechowuje wstępnie skonfigurowane raporty, a użytkownicy uzyskują dostęp do danych migawki bez obciążania warstwy db na na podstawie żądania.
Wszystko to jest od dawna rantem, który ilustruje, że stosowane zasady projektowania i sztuczki mogą się różnić, biorąc pod uwagę rolę tworzonej bazy danych. Mam nadzieję, że to pomocne.
źródło
Masz dobry pomysł. Możesz jednak to wyczyścić i usunąć niektóre tabele mapowania (ma *).
Co możesz zrobić, to w tabeli Departments dodaj CityId i DivisionId.
Poza tym myślę, że wszystko jest w porządku ...
źródło
Jedyne zmiany, które wprowadziłbym to:
1 - Zmień VARCHAR na NVARCHAR, jeśli wybierasz się na międzynarodowy rynek, możesz chcieć Unicode.
2- Jeśli to możliwe, zmień identyfikator użytkownika na GUID (unikalny identyfikator) (może to być po prostu moja osobista preferencja). Zakładając, że ostatecznie dojdziesz do punktu, w którym masz wiele środowisk (dev / test / staging / prod), możesz chcieć migrować dane z jednego do drugiego. Dzięki identyfikatorom GUID jest to znacznie łatwiejsze.
3- Trzy warstwy dla Twojej firmy -> Oddział -> Struktura działu może nie wystarczyć. Teraz może to być nadmierna inżynieria, ale możesz uogólnić tę hierarchię tak, abyś mógł obsługiwać n-poziomy głębi. To sprawi, że niektóre twoje zapytania będą bardziej złożone, więc może nie być to warte kompromisu. Ponadto może się zdarzyć, że każdy klient, który ma więcej warstw, może być łatwo „wypełniony” tym modelem.
4- Masz również status w tabeli klienta, który jest VARCHAR i nie ma linku do tabeli Statusy. Spodziewałbym się nieco większej jasności co do tego, co reprezentuje status klienta.
źródło
Nie. Wygląda na to, że projektujesz z dobrym poziomem szczegółowości.
Myślę, że kraje i firmy są w rzeczywistości tym samym podmiotem, co miasta i oddziały. Pozbyłbym się tabel krajów i miast (i Cities_Has_Departments) i, jeśli to konieczne, dodałbym flagę logiczną IsPublicSector do tabeli Firmy (lub kolumnę CompanyType, jeśli jest więcej możliwości niż po prostu sektor prywatny / sektor publiczny).
Myślę też, że wystąpił błąd podczas korzystania z tabeli Departamenty. Wygląda na to, że tabela Departments służy jako odniesienie do różnych rodzajów działów, które może mieć każdy dział klienta. Jeśli tak, należy nazwać DepartmentTypes. Ale twoi klienci (którzy, jak zakładam, są uczestnikami) nie należą do TYPU działu, należą do rzeczywistej instancji działu w firmie. W tej chwili będziesz wiedział, że dany klient należy do działu HR, ale nie który!
Innymi słowy, Klienci powinni być powiązani z tabelą, którą nazywacie Divisions_Has_Departments (ale którą nazwałbym po prostu Departamentami). Jeśli tak jest, musisz zwinąć Miasta do Dywizji, jak omówiono powyżej, jeśli chcesz użyć standardowej integralności referencyjnej w bazie danych.
źródło
Nawiasem mówiąc, warto zauważyć, że jeśli już generujesz CSV i chcesz załadować je do bazy danych mySQL, LOAD DATA LOCAL INFILE jest twoim najlepszym przyjacielem: http://dev.mysql.com/doc/refman/5.1/ pl / load-data.html . Warto również przyjrzeć się Mysqlimport i jest to narzędzie wiersza poleceń, które jest po prostu ładnym narzędziem do ładowania danych.
źródło
Większość rzeczy zostało już powiedzianych, ale czuję, że mogę dodać jedną rzecz: młodsi programiści dość często przejmują się wydajnością nieco z góry, a twoje pytanie o dołączanie do tabel wydaje się zmierzać w tym kierunku. Jest to anty-wzorzec opracowywania oprogramowania o nazwie „ Optymalizacja przedwczesna ”. Spróbuj pozbyć się tego odruchu :)
Jeszcze jedno: czy uważasz, że naprawdę potrzebujesz tabel „miasta” i „kraje”? Czy posiadanie kolumny „miasto” i „kraj” w tabeli departamentów nie wystarczyłoby na twoje przypadki użycia? Np. Czy twoja aplikacja musi wymieniać działy według miasta, a miasta według kraju?
źródło
Po komentarzach opartych na roli specjalisty Business Intelligence / Reporting i menedżera strategii / planowania:
Zgadzam się z powyższym wskazaniem Larry'ego. IMHO, To nie jest zbyt skomplikowane, niektóre rzeczy wyglądają trochę nie na miejscu. Dla uproszczenia oznaczyłem klienta bezpośrednio identyfikatorem firmy, opisem działu, opisem działu, identyfikatorem typu działu, identyfikatorem typu działu. Użyj identyfikatora typu działu i identyfikatora typu działu jako odniesień do tabel wyszukiwania i wewnętrznych pól raportowania / analizy w celu zapewnienia długoterminowej spójności.
Tabela paczek zawiera kolumnę „Kredyt”, czy nie powinna być tak naprawdę powiązana z tabelą podstawową klienta, więc jeśli liczba paczek jest widoczna, ile kredytów pozostało do zapłaty na przyszłe klasy? Aplikacja może zająć się obliczeniami i przechowywać je centralnie w tabeli klienta.
Informacje o firmie mogłyby użyć wielu innych pól, w tym oczywistego adresu / telefonu / itp. Informacja. Byłbym również przygotowany na dodanie w dłuższej perspektywie kolumn D&B „DUN” (Witryna / Oddział / Ostateczny), Dun i Bradstreet (D&B) mają ogromny katalog firm, a później znajdziesz informacje, które są bardzo pomocne do raportowania / analizy. Pozwoli to rozwiązać problem wielokrotnego podziału, o którym wspomniałeś, i pozwoli ci rozwinąć ich hierarchię dla pod / dywizji / oddziałów / etc. dużego korpusu.
Nie wspominasz o tym, z jak wieloma rekordami będziesz pracować, co może oznaczać przygotowanie się na dużą inicjatywę programistyczną, która mogłaby zostać wykonana szybciej i znacznie mniej problemów dzięki pakietowi oprogramowania do raportowania. Jeśli nie masz do czynienia z dużymi wierszami bazy danych (<65000), upewnij się, że MS-Access, OpenOffice (Base) lub powiązane rozwiązania do tworzenia raportów / aplikacji nie mogą załatwić sprawy. Sam dość często korzystam z bezpłatnego oprogramowania APEX firmy Oracle, które jest dostarczane z bezpłatną bazą danych Oracle XE.
FYI - Raportowanie wglądu: w przypadku dużych baz danych zazwyczaj masz dwie instancje bazy danych a) baza danych transakcji do rejestrowania każdego szczegółowego rekordu. b) baza danych raportowania (baza danych / hurtownia danych) umieszczona na osobnej maszynie. Aby uzyskać więcej informacji, wyszukaj w Google zarówno Schemat Star, jak i Schemat Snowflake.
Pozdrowienia.
źródło
Chcę zająć się tylko obawą, że dołączenie do wielu tabel wywoła uderzenie wydajności. Nie bój się normalizować, ponieważ będziesz musiał wykonać połączenia. Połączenia są normalne i oczekuje się ich w relacyjnych bazach danych i są zaprojektowane tak, aby dobrze z nimi radzić. Konieczne będzie ustawienie relacji PK / FK (w celu zapewnienia integralności danych należy to wziąć pod uwagę przy projektowaniu), ale w wielu bazach danych FK nie są automatycznie indeksowane. Ponieważ będą one używane w złączeniach, na pewno będziesz chciał zacząć od zindeksowania FKS. PK zazwyczaj otrzymują indeks tworzenia, ponieważ muszą być unikalne. To prawda, że projektowanie magazynu danych zmniejsza liczbę połączeń, ale zwykle nie dochodzi się do hurtowni danych, dopóki w jednym raporcie nie trzeba uzyskać milionów rekordów. Nawet wtedy prawie wszystkie hurtownie danych zaczynają się od transakcyjnej bazy danych w celu gromadzenia danych w czasie rzeczywistym, a następnie dane są przenoszone do hurtowni zgodnie z harmonogramem (co noc, co miesiąc lub cokolwiek potrzeba biznesowa). To dobry początek, nawet jeśli później trzeba zaprojektować hurtownię danych, aby poprawić wydajność raportu.
Muszę powiedzieć, że twój projekt jest imponujący dla studenta pierwszego roku CS.
źródło
To nie jest zbyt skomplikowane, tak podchodziłbym do problemu. Dołączenie jest w porządku, nie będzie dużego spadku wydajności (jest to absolutnie konieczne, chyba że zdenormalizujesz bazę danych, co nie jest zalecane!). W przypadku statusów sprawdź, czy możesz zamiast tego użyć typu danych wyliczeniowych do optymalizacji tej tabeli.
źródło
Pracowałem w domenie szkoleniowej / szkolnej i pomyślałem, że zwrócę uwagę na relację M: 1 między tak zwanymi „sesjami” (instancjami danego kursu) a samym kursem. Innymi słowy, twój katalog oferuje kurs („hiszpański 101” lub cokolwiek innego), ale możesz mieć dwa różne jego przykłady w ciągu jednego semestru (Tu-Th u Smitha, Wed-Fri u Jonesa).
Poza tym wygląda na dobry początek. Założę się, że przekonasz się, że domena klienta (wykresy prowadzące do „klientów”) jest bardziej złożona niż modelowana, ale nie przesadzaj z tym, dopóki nie zdobędziesz prawdziwych danych, które cię poprowadzą.
źródło
Przyszło mi do głowy kilka rzeczy:
Tabele zdawały się być dostosowane do raportowania, ale tak naprawdę nie prowadziły firmy. Myślę, że kiedy klient się zarejestruje, zasadniczo jest składane zamówienie na klienta uczestniczącego w liście sesji, które może dotyczyć wielu pracowników w jednej firmie. Wygląda na to, że tabela „zamówień” byłaby naprawdę w centrum systemu, a gromadzenie danych i raportowanie byłyby ostateczne. (Porównaj dokumenty papierowe, których używałeś do prowadzenia firmy z projektem bazy danych, aby sprawdzić, czy istnieje logiczne dopasowanie).
Firmy często nie mają oddziałów. Pracownicy czasami zmieniają działy / działy, może nawet w trakcie sesji. Firmy czasami dodają / usuwają / zmieniają nazwy działów / działów. Upewnij się, że możliwa zmiana treści twoich tabel w czasie rzeczywistym nie utrudnia późniejszego raportowania / grupowania. Przy tak dużej ilości danych kontaktowych w wielu tabelach może być konieczne wymuszenie bardzo ścisłej weryfikacji danych, aby raporty były zrozumiałe i pełne. Na przykład, gdy dodawany jest nowy klient, upewnij się, że jego firma / oddział / dział / miasto odpowiadają tym samym wartościom, co jego współpracownicy.
Pojęcie „paczek” wcale nie jest jasne.
Ponieważ wskazujesz, że jest to mała firma, zaskakujące byłoby, gdyby wydajność stanowiła problem, biorąc pod uwagę szybkość i wydajność obecnych maszyn.
źródło