Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL] struktura tabel, budowanie cmsa
pionas
post 25.01.2011, 15:33:06
Post #1





Grupa: Zarejestrowani
Postów: 70
Pomógł: 2
Dołączył: 25.03.2009
Skąd: Pionki

Ostrzeżenie: (0%)
-----


Cześć,

planuję napisać sobie prosty cmsik, mam pewną wizję ale muszę prosić o pomoc winksmiley.jpg
Tzn. interesuje mnie czy dobrze to zrobiłem (chodzi mi o to by było najlepiej)

Stopniowo będę pytał o kolejne tablice.
Teraz chciałbym zapytać o tabelę Users.
Cytat
id - int(80) auto_increment,
username - varchar(20),
password - varchar(32),
email - varchar(200),
sex - enum('m','f')
fName - varchar(20),
lName - varchar(50),
country - varchar(30),
city - varchar(40),
birthday - int(8),
about_me - text,
avatar - varchar(25),
foot - mediumtext,
created_at - int(14),
last_visit - timestamp,
actcode - varchar(50),
status - int(1).



birthday, created_at, last_visit - to są daty, pytanie jako jakie typu im dać?
birthday - Date
created_at, last_visit - datetime czy timestamp?
id - 80? nie za dużo?

about_me - informacje o użytkowniku, jakieś tam podane przez niego informacje
foot - stopka na forum, myślę że jakieś 3-4 linijki tekstu...

avatar - o 5 znaków więcej niż login bo nazwa pliku to będzie login.rozszerzenie (jpg, jpeg, gif, png)

Takie projekt może być?

[EDIT]
Lepsza jest jedna tabela czy rozbić to na dwie?
Cytat
Users:
id
username
password
email
created_at
last_visit
actcode
status

UsersInfo:
uid
fName
lName
sex
country
city
birthday
about_me
avatar
foot
questionmark.gif

Ten post edytował pionas 25.01.2011, 15:37:09


--------------------
Organizujesz konkurs? Chcesz coś wygrać? Wejdź na www.e-Konkursy.info :)
Go to the top of the page
+Quote Post
thek
post 25.01.2011, 16:13:14
Post #2





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Bazę analizuje się jako CAŁOŚĆ, a nie każdą tabelę z osobna, ponieważ ważne są także połączenia między nimi.
Ogólnie nie do końca chyba masz pojęcie co robisz. id(80) to nie id o 80 znakach. Liczba ta ma związek z ZEROFILL, czyli uzupełnieniem zerami. Większości osób jej ustawienie jest zbędne. Sens rozbijania na 2 jest zależny jak często na jakich danych są wykonywane operacje aktualizacji. Sens wbijania avatar jako login + rozszerzenie? żaden Wystarczy sam typ pliku. Created_at, last_visit: timestamp. Przyda się to później winksmiley.jpg Co do innych to trudno powiedzieć bo nie wszystkie są zrozumiałe (co to jest act_code ?).


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
#luq
post 25.01.2011, 16:43:52
Post #3





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


fName, created_at - całkiem inne notacje, zdecyduj się na jedną.
Używaj unsigned tak gdzie nie ma być liczb ujemnych (szczególnie id-iki)


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post
Crozin
post 25.01.2011, 16:43:58
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. 20 znaków na nazwę użytkownika to zdecydowanie za mało. Niektórzy mają długie nazwiska, a model "imię + nazwisko" nie jest jakiś wybitnie rzadki.
2. Po długości kolumny "password" zakładam, że hasło masz zamiar zapisywać w formie haszu MD5, czyż tak? Użyj innego algorytmu (czegoś z rodziny SHA2, np. SHA256) które są nieco bezpieczniejsze.
3. "fName", "lName" - stosuj jedną konwencję nazewnictwa. W przypadku MySQL jest to under_score_notation czyli "f_name". Poza tym używaj pełnych wyrażeń tam gdzie to możliwe, czyli "first_name" i "last_name".
4. Kraj/miasto - te dane powinny być znormalizowane.
5. "status" - użyj ENUM tak jak to zrobiłeś przy płci.

Cytat
Używaj unsigned tak gdzie nie ma być liczb ujemnych (szczególnie id-iki)
W większości przypadków to będzie jedynie większy problem. Raz, że mało prawdopodobne by przekroczył gdzieś limit. Dwa, że prawdopodobnie będzie używać PHP razem z tą bazą, a ten typów UNSIGNED nie obsługuje.

Ten post edytował Crozin 25.01.2011, 16:47:22
Go to the top of the page
+Quote Post
#luq
post 25.01.2011, 17:22:39
Post #5





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Cytat(Crozin @ 25.01.2011, 16:43:58 ) *
W przypadku MySQL jest to under_score_notation czyli "f_name"

MySQL radzi taką konwencje czy coś innego? Bo napisałeś tak jakby to była jedyna słuszna konwencja.

Cytat
Cytat
Używaj unsigned tak gdzie nie ma być liczb ujemnych (szczególnie id-iki)

W większości przypadków to będzie jedynie większy problem. Raz, że mało prawdopodobne by przekroczył gdzieś limit. Dwa, że prawdopodobnie będzie używać PHP razem z tą bazą, a ten typów UNSIGNED nie obsługuje.

Ale po co w polach gdzie nigdy nie będzie liczb ujemnych mieć zakres SIGNED? Wtedy możemy tak same wielkie liczby na wersji SIGNED zapisywać na 2 razy mniejszej liczbie bitów, więc nasza baza jest mniejsza, prawda? PHP tutaj jest nie ważny bo tu chodzi o bazę danych o jej szybkość i optymalizacje, nie bardzo rozumiem dlaczego taka wzmianka. PHP ma tylko signet int ale w czym to szkodzi jeśli chodzi o ten temat?

Ten post edytował #luq 25.01.2011, 17:23:22


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post
Crozin
post 25.01.2011, 17:42:45
Post #6





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
MySQL radzi taką konwencje czy coś innego? Bo napisałeś tak jakby to była jedyna słuszna konwencja.
Bo to jest jedyna słuszna konwencja. A słowa kluczowe pisane są wielkimi literami. Taka konwencja się przyjęła i pisanie inaczej jest błędne.
  1. DELETE FROM tbl_name WHERE col_name = other_col_name;


Cytat
Wtedy możemy tak same wielkie liczby na wersji SIGNED zapisywać na 2 razy mniejszej liczbie bitów
A bzdura. INT w MySQL to 32 bitowy format i zawsze zapisywany jest 32 bitami, niezależnie od wartości jaką reprezentuje. Zresztą... wszędzie tak jest. Modyfikatora UNSIGNED nie powinno się używać jeżeli rzeczywiście nie ma innego wyjścia. Komplikują one jedynie wiele spraw.

Ten post edytował Crozin 25.01.2011, 17:46:55
Go to the top of the page
+Quote Post
#luq
post 25.01.2011, 18:23:13
Post #7





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Cytat(Crozin @ 25.01.2011, 17:42:45 ) *
Bo to jest jedyna słuszna konwencja. A słowa kluczowe pisane są wielkimi literami. Taka konwencja się przyjęła i pisanie inaczej jest błędne.
  1. DELETE FROM tbl_name WHERE col_name = other_col_name;

Hm... Wielkie litery słów kluczowych - oka. Ale jakie są przesłanki by pisać abc_id zamiast abcId? Dla mnie istnieje przesłanka ku tej drugiej konwencji bo camelCase-a używam w każdym języku w którym pisze.

Cytat(Crozin @ 25.01.2011, 17:42:45 ) *
A bzdura. INT w MySQL to 32 bitowy format i zawsze zapisywany jest 32 bitami, niezależnie od wartości jaką reprezentuje. Zresztą... wszędzie tak jest. Modyfikatora UNSIGNED nie powinno się używać jeżeli rzeczywiście nie ma innego wyjścia. Komplikują one jedynie wiele spraw.

Jo, mój błąd smile.gif Ale możesz zrobić zamiast SIGNEG INT > UNSIGNET MEDIUMINT wprawdzie tracisz na zakresie ale ~16,8mln w większościach wypadków raczej starczy.
Dobra, to co mogą komplikować?


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post
Crozin
post 25.01.2011, 21:57:30
Post #8





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
Ale jakie są przesłanki by pisać abc_id zamiast abcId?
Bo takie ma ten język wypracowane konwencje. W SQLu używamy notacji under_score, w Javie zmienne nazywamy stosując notację camelCase. W SQLu słowa kluczowe piszemy wielkimi literami, w Javie stałe zapisujemy W_TEN_SPOSOB, a klasy/interfejsy CamelCasemZWielkiejLitery. Każdy (no nie każdy - PHP np. nie ma) język ma wypracowane swoje konwencje i się ich przestrzega - inaczej burdel powstaje (patrz: znowu to nieszczęsne PHP).

Cytat
Ale możesz zrobić zamiast SIGNEG INT > UNSIGNET MEDIUMINT
I...? W dużej części projektów to i SMALLINT można by użyć dla wielu rzeczy. Dla niektórych to i nawet TINYINT. To nie jest żaden argument.
Cytat
Dobra, to co mogą komplikować?
Po pierwsze SIGNED INT i UNSIGNED INT to dwa różne typy.
Po drugie wiele języków (a przecież to programy w nich napisane używają głównie tej bazy danych) nie wspiera typów unsigned, więc będą musiały użyć obszerniejszych typów (przykładowo Java będzie musiała skorzystać z LONG zamiast INT pobierając UNSIGNED INT).
Po trzecie http://www.google.com/search?client=opera&...-8&oe=utf-8 (ponieważ nie ma to związku z jakimś konkretnym językiem).
Po czwarte użycie BIGINT zamiast UNSIGNED INT nie będzie miało specjalnego wypływu na wydajność. Szczególnie, że w bazie będziesz miał ponad 4 mld rekordów - to one będą problemem.
Go to the top of the page
+Quote Post
pionas
post 25.01.2011, 22:41:18
Post #9





Grupa: Zarejestrowani
Postów: 70
Pomógł: 2
Dołączył: 25.03.2009
Skąd: Pionki

Ostrzeżenie: (0%)
-----


Mam taką mniej więcej wizję tego cmsika...

Cytat
Users:
id - int(10) auto_increment,
username - varchar(50),
password - varchar(64), // hash, sha256
email - varchar(200),
sex - enum('m','f').
first_name - varchar(20),
last_Name - varchar(50),
country - int(5),
city - int(5),
birthday - int(8),
about_me - text,
avatar - varchar(25),
foot - mediumtext,
created_at - timestamp,
last_visit - timestamp,
posts - int(10), // ilość postów na forum
ip - varchar(15), // ip aktualizowane przy logowaniu
admin - enum('n','y') // n - nie, y - tak
actcode - varchar(50), // unikalny kod do potwierdzenia na maila aktywacji konta...
status - enum('a', 'd', 'b'). // a - active, d - disable, b - block


Countries:
id - int(5),
name - varchar(40).

Cities:
id - int(5),
name - varchar(40).

CategoryArticles:
id - int(2),
name - varchar(200),
description - mediumtext,
total_articles - int(5).

Articles:
id - int(10),
cid - int(2), // id kategorii
title - varchar(250),
date_add - timestamp,
short_text - mediumtext,
long_text - text,
author - varchar(50), // kto dodał artykuł, myślę czyby tu nie dać ID konta osoby dodającej
sender - varchar(50), // kto nadesłał artykuł
date_end - timestamp, // data po której artykuł przestanie być wyświetlany...
icon - varchar(50), // nazwa obrazka do artykułu
views - int(5), // ilość wyświetleń artykułu
status - enum(0, 1, 2). // 0 - nieaktywny, 1 - aktywny, 2 - promowany

ArticlesComments:
id - int(10),
aid - int(10), // id artykułu
name - varchar(50), // nazwa/login osoby dodającej komentarz
mail - varchar(200),
text - text,
ip - varchar(15),
date_add - timestamp.


forum_cat
id - int(3)
name - varchar(100),
description - mediumtext,
position - int(2), // pozycja wyświetlania
posts - int(10), // ilość postów w kategorii
topics - int(10), // ilość topów w kategorii
last_post_id - int(10), // id ostatniego postu w tej kategorii
status - enum(1,2). // 1 - można zakładać topy, 2 nie można zakładać topów

forum_moderator:
fid - int(3) // id kategorii forum
uid - int(10) // id użytkownika

forum_top
id - int(10),
cid - int(3), // id kategorii
title - varchar(100), // nazwa topu
author - varchar(50), // osoba zakładająca top
email - varchar(200), // adres email osoby zakładającej top
date_add - timestamp // data utworzenia topu
replay - int(5) // ilość odpowiedzi
last_post_id - int(10) // id ostatniego postu
date_replay - timestamp // data ostatniej odpowiedzi
status - enum(1,2) // 1 - można pisać odpowiedzi, 2 zablokowany
min_post - int(5) // niektóre topy będą dostępne dla osób które mają określoną liczbę postów na swoim koncie...

forum_post
id - int(10)
tip - int(10), // id topu
author - varchar(50), // autor odpowiedzi
email - varchar(200), // adres email autora
ip - varchar(15),
date_add
edit_count - int(3), // ilość edycji postu
date_last_edit - timestamp // data ostatniej edycji
text - text // tresc wiadomosci

pw
id - int (10)
rid - int(10) // id osoby odbierającej wiadomość
sid - int(10) // id osoby wysyłającej wiadomość
title - varchar(150) // tytuł wiadomości
text - text // treść wiadomości
date - timestamp
readed - enum('y', 'n') // czy przeczytano wiadomość y - tak, n - nie

pw_type
pid - int(10) // id wiadomość
uid - int(10) // id użytkownika
type - enum(0, 1) // 0 - wiadomość wysłana, 1 - wiadomość zapisana


z PW chodzi mi o to żeby użytkownicy mogli je zapisywać w wysłanych, tak aby mieli historię rozmowy...

Na forum będzie możliwość zakładania topów i pisanie postów przez niezarejestrowane osoby stąd też jest author jako varchar i pole mail


--------------------
Organizujesz konkurs? Chcesz coś wygrać? Wejdź na www.e-Konkursy.info :)
Go to the top of the page
+Quote Post
#luq
post 26.01.2011, 23:12:32
Post #10





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Cytat(Crozin @ 25.01.2011, 21:57:30 ) *
I...? W dużej części projektów to i SMALLINT można by użyć dla wielu rzeczy. Dla niektórych to i nawet TINYINT. To nie jest żaden argument.

i wtedy już masz mniejszą ilość bitów przypadającą na to pole = mniejsza baza.

Cytat
Po pierwsze SIGNED INT i UNSIGNED INT to dwa różne typy.

No okej, ale gdzie komplikacja? To tak jakby napisać VARCHAR i INT to inne typy.

Cytat
Po drugie wiele języków (a przecież to programy w nich napisane używają głównie tej bazy danych) nie wspiera typów unsigned, więc będą musiały użyć obszerniejszych typów (przykładowo Java będzie musiała skorzystać z LONG zamiast INT pobierając UNSIGNED INT).

To jest chyba logiczne, po to używasz UNSIGNED żeby zwiększyć zakres. Jeśli gdzieś nie ma SIGNED/UNSIGNED tak jak w C++ to musi być wykorzystany obszerniejszy typ (jeśli po obu stronach na typ INT przypada tyle samo bitów). Poza tym w takim C++ w różnych kompilatorach można mieć różna liczba bitów przypadającą na jakiś typ prosty.

Cytat
Po trzecie http://www.google.com/search?client=opera&...-8&oe=utf-8 (ponieważ nie ma to związku z jakimś konkretnym językiem).

Okej, a więc używasz UNSIGNET MEDIUMINT i wtedy to się zmieści w typie INT

Cytat
Po czwarte użycie BIGINT zamiast UNSIGNED INT nie będzie miało specjalnego wypływu na wydajność. Szczególnie, że w bazie będziesz miał ponad 4 mld rekordów - to one będą problemem.

Cytat
Wiele języków (a przecież to programy w nich napisane używają głównie tej bazy danych) nie wspiera TAK DUŻYCH TYPÓW, więc będą musiały użyć obszerniejszych typów (przykładowo Java będzie musiała skorzystać z LONG zamiast INT pobierając BIGINT).


~Crozin, nie zrozum mnie źle. Nie rozumiem po prostu dlaczego tak negujesz UNSIGNED. Typy dobiera się pod dane jakie ma się w bazie. Jeśli przewidujesz, że tych danych będzie nie więcej jak 1 mln, to dobierasz najmniejszy typ który trzyma ten zakres. W tym przypadku typ X jest <-999 999, 999 999> to lepiej dobrać UNSIGNED X niż typ Y który jest zapisany na jednym bicie więcej niż typ X

~pionas, jeśli projektujesz bazę to skorzystaj z programu do tego - MySQL Workbench, SQL Yogi...


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post
Crozin
post 27.01.2011, 00:16:36
Post #11





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
No okej, ale gdzie komplikacja? To tak jakby napisać VARCHAR i INT to inne typy.
Nie możesz już przykładowo dwóch takich kolumn połączyć kluczem obcym.
Przyjmijmy, że `a` jest typu SIGNED i ma wartość -1, a `b` jest typu UNSIGNED i ma wartość 10. `a` - `b` = ? Równa się błąd. W przypadku dwóch typów UNSIGNED również trzeba najpierw sprawdzić czy aby na pewno `a` jest większe lub równe `b`.
Ogólnie cała arytmetyka w przypadku korzystania z typów UNSIGNED jest znacznie bardziej zakręcona i prowadzi do błędów.

Pewnie, czasami aż prosi się o to by skorzystać z typów UNSIGNED, przykładowo 3 x UNSIGNED TINYINT dla kolejnych kanałów koloru zapisanego jako RGB. UNSIGNED SMALLINT dla portu z którego ma korzystać aplikacja. Typy te idealnie wpisują się w przechowywane w nich dane, ale... cały problem można załatwić stosując obszerniejszy typ (przykładowo SMALLINT zamiast UNSIGNED TINYINT). Akurat różnice w wielkości bazy przy korzystaniu z INT zamiast MEDIUMINT w większości aplikacji będą marginalne. Na wydajność też nie będzie to miało wpływu.
Trzeba oczywiście zaznaczyć, że typ bez znaku jest też czasami dużo wygodniejszy, np. w przypadku algorytmów, które zakładają operację na bitach typu bez znaku. I w takich przypadkach można pokusić się o ich użycie.

Ogólna zasada jest taka, że jeżeli jedyna korzyść wynikająca z użycia typu bez znaku ma ograniczać się do zakresu możliwych do przechowywania danych powinniśmy skorzystać z typu obszerniejszego. Korzyści płynące z mniejszego typu nie są warte masy ograniczeń, nie do końca jasnego (dla dużej części programistów) sposobu działania itp.

Cytat
Jeśli gdzieś nie ma SIGNED/UNSIGNED tak jak w C++
Ale C/C++ mają typy UNSIGNED. winksmiley.jpg Ale przyjmijmy, że miałeś na myśli na przykład wspomnianą już przeze mnie Javę.
Cytat
Poza tym w takim C++ w różnych kompilatorach można mieć różna liczba bitów przypadającą na jakiś typ prosty.
Tak, masz rację ponieważ standard określa jedynie minimalną liczbę bitów na typ, a nie konkretną wartość. Ale prawda jest taka, że w większości mam do czynienia ze "standardowym" modelem, gdzie INT ma 32 bity, a BYTE 8.
Go to the top of the page
+Quote Post
Ulysess
post 27.01.2011, 01:19:08
Post #12





Grupa: Zarejestrowani
Postów: 695
Pomógł: 65
Dołączył: 27.07.2009
Skąd: Y

Ostrzeżenie: (0%)
-----


hmm Users:
Przedewszystkim .. na pola typu INT nie ustawiaj maksymalnej ilości znaków (tak jak napisał thek - to ma znaczenie przy ZEROFILL)
country - TINYINT Unsigne (po co INT skoro ma zakres 2,1.. mld jeśli państwa jest ~200 )
city - tutaj raczej był dał char 32

jak dla mnie tabela cities jest bez sensu bo jak .. będziesz trzymał wszystkie nazwy miast,miejscowości,wsi ? :|
Go to the top of the page
+Quote Post
Crozin
post 27.01.2011, 02:14:49
Post #13





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
country - TINYINT Unsigne (po co INT skoro ma zakres 2,1.. mld jeśli państwa jest ~200 )
Nie ma to jakieś specjalnego znaczenia, więc...
Cytat
city - tutaj raczej był dał char 32
Nie CHAR, a VARCHAR. Pomiędzy 32, a 40 nie będzie kompletnie żadnej różnicy (po stronie obsługi przez silnik) o ile dobrze kojarzę.
Cytat
jak dla mnie tabela cities jest bez sensu bo jak .. będziesz trzymał wszystkie nazwy miast,miejscowości,wsi ? :|
Może przechowywać tylko te podane przez użytkowników. A przed dodaniem nowych pozycji sprawdzić (np. wykorzystując API GoogleMaps) szczegółowe informacje n/t miejscowości, znormalizować dane podane przez użytkownika itd.

@pionas:
1. Daruj sobie podawanie n przy INT(n). I tak nie korzystasz z ZEROFILL i prawdopodobnie nigdy nie będziesz (bo wygodniej takie formatowanie zrobić po stronie PHP).
2. Sól hasła (co będzie się wiązało z powstaniem nowej kolumny przykładowo salt CHAR(20)) - Temat: podwojne hashowanie hasel (w tym temacie o ile dobrze pamiętam jest dosyć dobrze omówiona kwestia składowania haseł; oczywiście, żeby Ci nie przyszło do głowy n-krotnie haszować hasła).
3. Daty przechowuj w formacie DATE, ewentualnie DATETIME. Nie stosuj formy unixowego timestampa bo zakres dat które da się przy pomocy tego jest bardzo ograniczona (na pewno nie można daty urodzenia przechowywać przy pomocy tego).
4. foot to jest stopa, a nie sygnaturka/podpis/motto użytkownika. Nazwa signature chyba tutaj najlepiej pasuje.
5. IP w żadnym wypadku nie przechowuj jako VARCHAR(15) bo to nie jest format adresu IP. IPv4 to 32 bitowa liczba, więc... przechowuje się ją jako liczbę całkowitą (INT). Mimo wszystko i tak, nie powinieneś takiego formatu stosować bo IPv4 jest już stopniowo zastępowane przez IPv6 czyli 128 bitową liczbę. Tutaj trochę informacji o tym jak najlepiej przechowywać tak dużą liczbę.
6. Przy ENUM-ach możesz sobie podać pełne wyrazy, a nie jakieś pojedyncze literki. Czyli yes, no, inactive, active, promoted, a nie jakieś y, n, i, a, p itd.
7. Miasta raczej powinieneś przyporządkować konkretnym państwom.
8. Nieco subiektywna uwaga. Nie stosuj skrótowców typu cid tylko podaj pełne category_id. Znacznie lepiej się później czyta/analizuje zapytania pozbawione niejednoznacznych skrótów.
9. Stosuj się do jakiś konwencji nazewnictwa. Raz nazwę utworzenia obiektu nazywasz created_at, raz date_add (to nawet nie jest poprawny angielski). Raz korzystasz z konwencji under_score, raz z camelCase.
10. Skoro korzystasz już z relacyjnej bazy danych jaką jest MySQL to używaj tych relacji. W tabeli article, forum_post itp. wystarczy Ci ID użytkownika, który dodał artykuł - nie powielaj zbędnie danych.
11. Ogólnie popracuj nad swoim nazewnictwem. forum_top wtf? forum_thread czy forum_topic, a nie jakieś "top" co nie do końca wiadomo co może oznaczać. Takich bezsensownych nazw jest znacznie więcej.
Go to the top of the page
+Quote Post
pionas
post 27.01.2011, 19:13:04
Post #14





Grupa: Zarejestrowani
Postów: 70
Pomógł: 2
Dołączył: 25.03.2009
Skąd: Pionki

Ostrzeżenie: (0%)
-----


Cytat
Users:
id - int(10) auto_increment, UNSIGNED
username - varchar(50),
password - varchar(64), // hash, sha256, salt...
email - varchar(200),
sex - enum('male','female').
first_name - varchar(20),
last_Name - varchar(50),
country_id - tinyint(3) UNSIGNED
city - smaillint(5) UNSIGNED
birthday - date,
about_me - text,
avatar - varchar(25),
signature - mediumtext,
created_at - datetime,
last_visit - datetime,
posts - smallint(5) UNSIGNED // ilość postów na forum
ip - int(10) UNSIGNED // ip aktualizowane przy logowaniu, funkcja ip2long
admin - enum('no','yes')
actcode - varchar(50), // unikalny kod do potwierdzenia na maila aktywacji konta...
status - enum('active', 'disable', 'block').


Countries:
id - tinyint(3) auto_increment, UNSIGNED
name - varchar(40).

Cities:
id - smaillint(5) auto_increment, UNSIGNED,
country_id - tinyint(3) UNSIGNED,
name - varchar(40).

CategoryArticles:
id - smaillint(2) auto_increment, UNSIGNED
name - varchar(200),
description - mediumtext,
total_articles - smaillint(5) UNSIGNED.

Articles:
id - int(10) auto_increment, UNSIGNED
category_id - smaillint(2), // id kategorii
title - varchar(250),
date_added - datetime,
short_text - mediumtext,
long_text - text,
author - varchar(50), // kto dodał artykuł, myślę czyby tu nie dać ID konta osoby dodającej
sender - varchar(50), // kto nadesłał artykuł
date_end - datetime, // data po której artykuł przestanie być wyświetlany...
icon - varchar(50), // nazwa obrazka do artykułu
views - smaillint(5) UNSIGNED, // ilość wyświetleń artykułu
status - enum("active", "inactive", "promo").

ArticlesComments:
id - int(10) auto_increment, UNSIGNED
article_id - int(10) UNSIGNED, // id artykułu
name - varchar(50), // nazwa/login osoby dodającej komentarz
mail - varchar(200),
text - text,
ip - int(10),
date_add - datetime.


forum_cat
id - int(3) auto_increment, UNSIGNED
name - varchar(100),
description - mediumtext,
position - smallint(2) UNSIGNED, // pozycja wyświetlania
posts - int(10) UNSIGNED, // ilość postów w kategorii
topics - int(10) UNSIGNED, // ilość topów w kategorii
last_post_id - int(10) UNSIGNED, // id ostatniego postu w tej kategorii
status - enum("open", "closed").

forum_moderator:
forum_category_id - int(3) auto_increment, UNSIGNED // id kategorii forum
user_id - int(10) UNSIGNED // id użytkownika

forum_topic
id - int(10) auto_increment, UNSIGNED
category_id - smallint(3) UNSIGNED, // id kategorii
title - varchar(100), // nazwa topu
author - varchar(50), // osoba zakładająca top
email - varchar(200), // adres email osoby zakładającej top
date_added - datetime // data utworzenia topu
replay - smallint(5) UNSIGNED// ilość odpowiedzi
last_post_id - int(10) UNSIGNED // id ostatniego postu
date_replay - datetime // data ostatniej odpowiedzi
status - enum("open", "closed", "blocked")
min_post - smallint(5) UNSIGNED // niektóre topy będą dostępne dla osób które mają określoną liczbę postów na swoim koncie...

forum_post
id - int(10) auto_increment, UNSIGNED
toptic_ip - int(10) UNSIGNED, // id topu
author - varchar(50), // autor odpowiedzi
email - varchar(200), // adres email autora
ip - int(10) UNSIGNED,
date_added - datetime,
edit_count - smallint(3) UNSIGNED, // ilość edycji postu
date_last_edit - datetime // data ostatniej edycji
text - text // tresc wiadomosci

pw
id - int (10) auto_increment, UNSIGNED
receiver_user_id - int(10) UNSIGNED // id osoby odbierającej wiadomość
sender_user_id - int(10) UNSIGNED // id osoby wysyłającej wiadomość
title - varchar(150) // tytuł wiadomości
text - text // treść wiadomości
date - datetime
readed - enum('yes', 'no')

pw_type
pw_id - int(10) UNSIGNED // id wiadomość
user_id - int(10) UNSIGNED // id użytkownika
type - enum("sent", "saved")



Crozin przy artykułach czy forum nie mogę dać samych ID użytkoników, bo pisać mogą też niezarejestrowani użytkownicy...

Ten post edytował pionas 27.01.2011, 19:14:29


--------------------
Organizujesz konkurs? Chcesz coś wygrać? Wejdź na www.e-Konkursy.info :)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 2.05.2025 - 04:23