(Jatkoa aiempaan.)
Nyt on tarkoituksena että käyttäjä pystyy seuraamaan tietyntyyppisiä uutisia. Miten kannattaisi tallettaa tietokantaan uutistyypit (0,1,2) joita käyttäjä seuraa,niin että ne olisi helposti haettavissa?
Jotenkin tyyliin.
Create Table `user_newstype` ( `user` Int(10) Not Null, `newstype` Int(10) Not Null, Primary Key (`user`, `newstype`), Foreign Key (`user`) References `user`(`id`), Foreign Key (`newstype`) References `newstype`(`id`) )
Tai sitten lisäksi autoincrementti ja se primary keyksi.
Enkö voi tehdä käyttäjätauluun uutta saraketta, tyyliin subscribed_news. Haluaisin hakea tyyliin SELECT * FROM users WHERE subscribed_news = 0
tuo 0 voisi olla siis myös 1 tai 2.
Jos käyttäjälle riittää yksi ryhmä (uutinen.tyyppi = käyttäjä.seuraa) tai kaikki pienemmät ryhmät (uutinen.tyyppi <= käyttäjä.seuraa), voit vain lisätä uuden sarakkeen. Jos pitää pystyä tekemään jokin mielivaltainen valinta (esim. ryhmät 0 ja 2), tarvitset joko SET-sarakkeen tai erillisen taulun; näistä erillistä taulua pidetään yleisesti joustavampana ja helpommin hallittavana.
Olli kirjoitti:
Enkö voi tehdä käyttäjätauluun uutta saraketta, tyyliin subscribed_news. Haluaisin hakea tyyliin
SELECT * FROM users WHERE subscribed_news = 0
tuo 0 voisi olla siis myös 1 tai 2.
Alkuperäisessä viestissä kysyit monikossa (...uutistyypit joita...) jolloin tietenkään ei ole mahdollista tehdä vain yhdellä numerolla yhdessä sarakkeessa.
Ja ellet tosiaan käsin rustaile niitä SQL-kyselyitä, niin yhdellä sarakkeella ja välitaululla ei ole kummoistakaan eroa koodaamisen kannata.
Esim. Linq:
from u in db.Users where u.subscribed_news == 1
vs
from u in db.Users where u.user_newstype.newstype == 1
Tein nyt uuden taulun subscriptions
, jossa on sarakkeet: id (INT), userid (INT), newstype (INT)
Miten tuohon newstypeen saisin useampia uutistyyppejä?
Yhdellä rivillä kerrotaan aina yhden käyttäjän yksi tyyppi. Jos käyttäjä haluaa monta tyyppiä, pitää tehdä monta riviä.
Ok, no miten saan haettua esim. kaikki uutistyyppiä 2 seuraavat käyttäjät?
Tuossa edellisessä viestissäni viimeisellä rivillä oli esimerkki miten se tapahtuisi esim C#:ssa (EF ja LinQ). 1 tilalle vaan 2.
Ihan perus SQL:llä:
select U.* from `users` U join subscriptions S on U.id=S.userid where S.newstype = 2
Okei, mutta entäs sitten kun käyttäjä voi profiilistaan valita seurattavat uutistyypit. Miten kannattaisi tallentaa ne? Ongelmaksihan tulee se, että jos päätän lisätä uuden uutistyypin, niin miten tämä vaikuttaa vanhoihin käyttäjiin?
Onko tätä järkevämpää tapaa olemassa:
$query = $db->prepare("DELETE FROM subscriptions WHERE userid = ?"); // poistetaan kaikki entiset seurannat $query->execute(array($userId)); // luodaan uudet seurannat lomakkeen tietojen mukaisesti if($_POST["type0"] == "true"){ $query = $db->prepare("INSERT INTO subscriptions (userid, newstype) VALUES (?, ?)"); $query->execute(array($userId, "0")); } if($_POST["type1"] == "true"){ $query = $db->prepare("INSERT INTO subscriptions (userid, newstype) VALUES (?, ?)"); $query->execute(array($userId, "1")); } if($_POST["type2"] == "true"){ $query = $db->prepare("INSERT INTO subscriptions (userid, newstype) VALUES (?, ?)"); $query->execute(array($userId, "2")); }
$query->execute(array($userId, $_POST['type']));
Kaikkien poisto ja valittujen lisäys on ihan käypä tapa muuttaa valintoja. Hienompia ratkaisuja on, esimerkiksi voisit hakea aiemmat valinnat ja lisätä tai poistaa vain muuttuneet, mutta käytännön hyöty on (tässä tapauksessa) mitätön.
Voit kutsua preparea vain kerran ja käyttää samaa $query-muuttujaa monta kertaa. Lisäksi kannattaa käyttää hakasulkuja kenttien nimissä, jolloin tiedot saa taulukkona ja niiden käsittely koodissa on helpompaa.
tyyppi 0: <input type="checkbox" name="type[]" value="0" /> tyyppi 1: <input type="checkbox" name="type[]" value="1" /> tyyppi 2: <input type="checkbox" name="type[]" value="2" />
if (!empty($_POST["type"]) && is_array($_POST["type"])) { $query = $db->prepare("INSERT ..."); foreach ($_POST["type"] as $type) { $query->execute(array($userId, $type)); } }
The Alchemist: Mitenkä laitat tuolla yhdellä executella N:N-liitostauluun epämääräisen määrän (0–3) liitoksia ja poistat ylimääräiset liitokset? Onko nyt mitään järkeä ”vastata” kysymyksiin, jos ei viitsi edes katsoa, mitä kysytään?
Metabolixin ratkaisussa voi lisätä esimerkiksi tyypin 5 tai 6 jos haluaa, tämä ei varmasti ole tarkoitus?
Miettisit vähän Metabolix ennen kuin vastaat..
qeijo kirjoitti:
Metabolixin ratkaisussa voi lisätä esimerkiksi tyypin 5 tai 6 jos haluaa, tämä ei varmasti ole tarkoitus?
Miettisit vähän Metabolix ennen kuin vastaat..
Entäs jos käyttäjä haluaa seurata kaiken tyyppisiä viestejä, niin eikös silloin juurikin laiteta kaikki aktiiviseksi? Oletan tämän juuri olleen tarkoitus.
qeijo: Taulussa piti olla vierasavain (ks. Grezin neuvo), jolloin olemattomia tyyppejä ei voisi lisätä. Olli ei myöskään kysynyt oikeuksien tarkistamisesta, joten en ottanut siihen itsekään kantaa.
Tietenkin jos halutaan rajoittaa tyyppejä, voidaan lisätä tieto sallituista tyypeistä ja ennen execute-riviä tyypin tarkistus.
Aihe on jo aika vanha, joten et voi enää vastata siihen.