Autor Zpráva
marekjanu
Profil *
Ahoj,
chci vytvořit "docházkový systém" pro pěvecký sbor.
Zamýšlel jsem se již víckrát nad podobným problémem, ale nikdy mne nenapadlo nějaké jednoznačně nejlepší řešení.
Popíšu ve zkratce co by to mělo umět: evidovat, kdo na které zkoušce byl či nebyl a zda svoji neučást omluvil

napadlo mne založit tabulku ve tvaru
                            člen1 id       člen2 id	člen 3 id	člen4 id
zk datum1	U	NN	ON	NN
zk datum2	U	ON	U	U
zk datum3	ON	U	U	ON
zk datum4	NN	ON	U	NN


U	účast			
NN	neomluv. neúčast			
ON	omluv. neúčast	


problém však vidím v tom, že když rozšířím tabulku o nové sloupce (což by neměl být problém), tak bych měl upravit i příkazy vkládající informace o jednotlivých zkouškách do té databáze, což už pro mne problém je

navíc v současné době mám samostatnou tabulku se členy (id, jméno, příjmení, mail, hlas...) a v té nové tabulce bude každý sloupec označen jenom id daného člena, ve výstupních datech však samozřejmě chci zobrazovat jména členů + hlas (tzn. dodělat nějaký skriptík, který by se podíval, jaké jméno a hlas přísluší danému id v té již zavedené tabulce, což snad není problém)

slyšel jsem něco o virtuálních či asociačních tabulkách, ale nic o tom nevím a zajímalo by mne, zda je to pro tento případ použitelné
marekjanu
Profil *
hmm, tak trošku se to rozházelo - záhlaví sloupců té tabulky se přesunuly doprava, ale snad je to pochopitelné
klingac
Profil
ja by som to riesil asi takto:
CREATE TABLE skuska (
  skuska_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  datum DATE NULL,
  PRIMARY KEY(skuska_id)
)
TYPE=InnoDB;

CREATE TABLE typ_ucasti (
  typ_ucasti_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  nazov_typu_ucasti VARCHAR NULL,
  PRIMARY KEY(typ_ucasti_id)
)
TYPE=InnoDB;

CREATE TABLE hlasy (
  hlas_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  nazov_hlasu VARCHAR NULL,
  PRIMARY KEY(hlas_id)
)
TYPE=InnoDB;

CREATE TABLE clen (
  clen_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  hlasy_hlas_id INTEGER UNSIGNED NOT NULL,
  meno VARCHAR NULL,
  prijmeni VARCHAR NULL,
  hlas INT NULL,
  PRIMARY KEY(clen_id),
  INDEX clen_FKIndex1(hlasy_hlas_id),
  FOREIGN KEY(hlasy_hlas_id)
    REFERENCES hlasy(hlas_id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
)
TYPE=InnoDB;

CREATE TABLE clen_has_skuska (
  clen_id INTEGER UNSIGNED NOT NULL,
  skuska_id INTEGER UNSIGNED NOT NULL,
  typ_ucasti_id INTEGER UNSIGNED NOT NULL,
  PRIMARY KEY(clen_id, skuska_id),
  INDEX clen_has_skuska_FKIndex1(clen_id),
  INDEX clen_has_skuska_FKIndex2(skuska_id),
  INDEX clen_has_skuska_FKIndex3(typ_ucasti_id),
  FOREIGN KEY(clen_id)
    REFERENCES clen(clen_id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION,
  FOREIGN KEY(skuska_id)
    REFERENCES skuska(skuska_id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION,
  FOREIGN KEY(typ_ucasti_id)
    REFERENCES typ_ucasti(typ_ucasti_id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
)
TYPE=InnoDB;


vizualne schema vyzera takto

do tabulky clen sa ukladaju informacie o clenoch, je mozne ju kedykolvek rozsirit o dalsie potrebne stlpce.
zoznam moznych hlasov je v tabulke hlasy, zoznam skusok je v tabulke skuska. zatial sa tam nachadza iba datum konania skusky, je mozne pridat aj stlpce pre miesot konania, typ skusky a pod. v tabulke typ_ucasti su zaznamy ako účast, neomluv. účast , omluv. neúčast, choroba, atd.
zaznamy o tom ktory clen bol na ktorej skuske sa udrzuju v tabulke clen_has_skuska. pomocou primarnych a cizich klucov je zabezpecene ze ze na kazdom riadku tabulky bude pre danu skusku iba jeden zaznam o clenovi a zaroven budeme mat zaznamenany aj typ ucasti clena
Mastodont
Profil
marekjanu
Pročti si základy tvorby relačních tabulek. Sloupce člen1, člen2, člen3 - to je velmi častá chyba začátečníků, žádné opakované sloupce se v tabulkách vyskytovat nemají. Potřebuješ tři tabulky - členové, zkoušky, účast, v tabulce účast budou jen tři sloupce - id člena, id zkoušky a typ účasti (přítomen, omluven, neomluven).
marekjanu
Profil *
Mastodont

Vopravdu se mi líbí to co píšeš.

Já už dvě tabulky mám: členové, zkoušky (clenove, zkousky)
tab. členové obsahuje ID, jméno, příjmení...
tab. zkoušky obsahuje ID, datum, místo...

nyní tedy založím tabulku dochazka se sloupci IDclena, IDzkousky,ucast

základy tvorby relačních tabulek již čtu http://www.linuxsoft.cz/article.php?id_article=827

když se teď nad tím tak zamyslím, tak ta tabulka dochazka bude mít za chvilku relativně mnoho řádků (neboť členů je dnes 40 a co zkouška, tak 40 řádek), to ale nevadí

bohužel si nyní nedokáži představit, jak mám dál postupovat (ovládat to PHP)

moje ÚVAHA:

je jasné, že tabulku dochazka budu chtít začít plnit daty. nejdříve však musím vybrat nějakou zkoušku v tabulce zkousky. pak si nechám vygenerovat z tabulky clenove seznam všech členů do formuláře. formulář odešle data ve tvaru (schematicky):

$idzkousky=idzkousky
$idclena1=pritomen
$idclena2=omluven
$idclena3=pritomen
$idclena4=neomluven
.
.
.
$idclena40=pritomen

a uložím to do tabulky dochazka:

IDclena,IDzkousky,ucast

$idclena1,idkousky,pritomen
$idclena2,idzkousky,omluven
$idclena3,idzkousky,pritomen
.
.
.
$idclena40,idzkousky,pritomen



a potom si budu chtít nechat zobrazit, kteří členové byli na zkoušce s IDzkousky "idzkousky"

select * from dochazka WHERE IDzkousky=idzkousky AND ucast=pritomen


je tahle úvaha správná?
Tomasds
Profil
marekjanu
je tahle úvaha správná?

Ano. Jen bych ucast nedělal jako textový sloupec, ale jako integer.
A s počtem řádků si nedělej starosti. Tabulka o třech sloupcích ve formátu integer a pár desítkách tisíc řádků není problém.
nightfish
Profil
Tomasds
Jen bych ucast nedělal jako textový sloupec, ale jako integer
a proč ne char(1)?
Tomasds
Profil
nightfish
a proč ne char(1)?

Nevím. Já bych prostě udělal integer, mám jaksi podvědomě za to, že to je úspornější a rychlejší. Ale jednak se můžu plést a i kdyby tam rozdíl byl, tak bude minimální.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0