Mikä olisi hyvä tietokantarakenne synonyymi-sanastolle?
Tällä hetkellä kaikki sanat ovat samassa sarakkeessa pilkulla erotettuna :(
Tällä hetkellä kaikki sanat ovat samassa sarakkeessa pilkulla erotettuna :(
Turvaa tilisi vahvistamalla puhelinnumerosi. Voit silloin palauttaa unohtuneen salasanan tekstiviestillä.
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 10
Vanhimmat
Ei hyvä, ei. Toki voi toimia nyt, mutta koitas muuttaa jotain sanaa jne... niin jopas onkin ongelmia ;)
Kanta rakennetta ei voi sanoa mitään näin vähillä tiedoil. Esim tämmönen
Sanat
SID | sana
1 | tietokone
Synonyymit
ID | SID | synonyymi
5 | 1 | tietsikka
6 | 1 | tietsuli
Tällöin pystyt muokkaamaan sanoja huomattavasti helpommin
>Synonyymit
ID | SID | synonyymi
5 | 1 | tietsikka
6 | 1 | tietsuli
Mutta tietsuli on myös tietsikan ja tietokoneen synonyymi
Samoin tietsikka on tietsulin ja tietokoneen synonyymi
Aika sekavaksi menee, ja päivitettävyys kärsii jos kaikki laitetaan ristiin sinne taulukkoon.
Miten varsinaisen sovelluksen pitäisi toimia.
Jos ajatellaan esim sovelluksen sanahakua
esim jos käyttäjä kirjoittaa tietsikka tai compuutteeri niin kaikki synonyymisanastossa viittaa tietenkin tietokone-sanaan ja nyt voidaan lähteä etsimään kaikki tuotteet joissa tuotteena on tietokone.
Ahaa, siinätapauksessa yks vaihtoehto on tehdä näin.
Synonyymit
ID | SID | sana
1 | 1 | tietokone
2 | 1 | tietsuli
3 | 1 | tietsikka
Tosta on helppo hakea ihan perus haulla halutun sanan synonyymit. Sekä päivitys on helppoa. Tosta voi myös jättää pois avainsanan SIDin jos haluaa, tosin sitten joutuu tekemään vähän erillaisempia kyselyitä.
Itseasiassa tossa aikasemmassa esimerkissä ei tarvitse laittaa tietoja noin ristiin, haetaan vain molemmista tauluista, tai sit lisätään perus sana synonyymi tauluun, tosin ei moinen taida olla järkevää.
Lähtökohtia:
Uusien sanojen syötön pitää olla mahdollisimman nopeaa.
Synonyymien lisääminen sanalle oltava mahdollisimman nopeaa.
{ Tietokone, Tietsikka, Tietsuli } -tapauksessa syötettäviä sanoja pitää olla kolme, luotavia synonyymilinkkejä kaksi.
Varsinaiset kyselyt ja/tai niiden tuloksia käyttävä softa voi sitten olla kuinka monimutkainen tahansa.
asiaan:
Kaksi taulua, sana-taulu sekä syno(-nyymi)-taulu. Postgre-syntaksin mukaiset taulunluontiskriptit.
-- Listaa kaikki sanakirjan sanat
--
CREATE TABLE sana (
sanaid INT NOT NULL,
sana varchar(100) NOT NULL,
PRIMARY KEY (sanaid)
);
-- listaa sana-taulussa olevien sanojen välisiä
-- linkkeja
CREATE TABLE syno (
sanaid INT NOT NULL,
synoid INT NOT NULL,
PRIMARY KEY (sanaid, synoid)
);
taulujen sisältö jotain tällaista:
sana:
sanaid | sana
------------------
1 | Tietokone
2 | Tietsikka
3 | Tietsuli
insert into sana (sanaid, sana) values (1, 'Tietokone');
insert into sana (sanaid, sana) values (2, 'Tietsikka');
insert into sana (sanaid, sana) values (3, 'Tietsuli');
ja syno:
sanaid | synoid
----------------------
1 | 2
1 | 3
insert into syno (sanaid, synoid) values (1, 2);
insert into syno (sanaid, synoid) values (1, 3);
Eli hyvin pitkälle sama startti kuin mitä nimimerkki "-----------" ehdotti. Tämän mallin hyvänä puolena siis simppeli kantarakenne ja nopea tietojen sisäänsyöttö.
'Tietokone'-sanan synonyymit saat selville seuraavasti:
q1: 'Tietokone'-sanan id:n saat selville kyselyllä:
select sanaid from sana where sana = 'Tietokone';
sanaid
--------
1
(1 row)
q2: Tätä vastaavat synonyymi-id:t taas:
select synoid from syno where sanaid in (select sanaid from sana where sana = 'Tietokone');
synoid
--------
2
3
(2 rows)
q3: Ja varsinaiset synonyymisanat vaikka näin:
select synoid, sana from syno, sana where syno.sanaid in (select sanaid from sana where sana = 'Tietokone') and sana.sanaid = syno.synoid;
synoid | sana
-------- -----------
2 | Tietsikka
3 | Tietsuli
(2 rows)
Ongelmaksi jää "Tietsuli"-sanan yhdistäminen "Tietsikka":an. Yhdellä kyselyllä et tuota taio, mutta on toki mahdollista tehdä monta kyselyä. Ensimmäisen synonyymeja tuottava kyselyn q3 tulokset voidaan näyttää suoraa käyttäjälle. Jos käyttäjä halusi synonyymeja sanalle 'Tietokone', niin kysely q3 palautti hänelle kaksi vastausta, 'Tietsikka' ja 'Tietsuli', niin sama kysely 'Tietsuli'-sanalle palauttaa nolla vastausta.
Homman juju on siinä, että 'Tietsuli' on linkattu "käänteisesti" 'Tietokone'-sanaan syno-taulussa. Eli kysely q3:sta pitää muuttaa siten, että:
q4: 'Tietsuli'-sanan id:n saat selville kyselyllä:
select sanaid from sana where sana = 'Tietsuli';
sanaid
--------
3
(1 row)
q5: Tätä vastaavat synonyymi-id:t käänteisesti haettuna taas:
select sanaid from syno where synoid in (select sanaid from sana where sana = 'Tietsuli');
sanaid
--------
1
(1 row)
joka on siis 'Tietokone'-sanan id.
q6: Ja tätä vastaava sana:
select sana from sana where sanaid in (select sanaid from syno where synoid in (select sanaid from sana where sana = 'Tietsuli'));
sana
-----------
Tietokone
(1 row)
Tämän haun tulos voidaan liittää synonyymihaun tuloksiin.
q7: Ja lopu synonyymisanat 'Tietsuli':n kautta saadulle tulokselle samalla tavalla kuin kohdassa q3. Mutta koska q3 tuottaa myös 'Tietsuli'-sanan, se pitää ottaa pois tuloksista.
select synoid, sana from syno, sana where syno.sanaid in (select sanaid from sana where sana = 'Tietokone') and sana.sanaid = syno.synoid and sana not like 'Tietsuli';
synoid | sana
-------- -----------
2 | Tietsikka
(1 row)
Joka myös liitetään tuloksiin.
--
Nyt siis kyselyillä q1-q3 saatu 'Tietokone'-haulla synonyymit 'Tietsikka' ja 'Tietsuli'
Kyselyillä q4-q7 saatu 'tietsuli'-haulla synonyymit 'Tietokone' ja 'Tietsikka'
Myönnetään, varsinkin kohdan q6 kysely kaksinkertaisine sisäkkäisine kyselyineen on hiukka ruma. Mutta tämä nyt ensimmäisenä harjoituksena..
Tämän mallin ongelmana on se, että haku synonyymiyden haku ei ulotu kovinkaan pitkälle. Jos 'Tietsikka'-sana olisikin linkattu vaikka sanaan 'Romutoosa',
insert into sana (sanaid, sana) values (4, 'Romutoosa');
insert into syno (sanaid, synoid) values (2, 4);
, niin silloin synonyymihaku sanalla 'Tietokone' ei löydä tulosta 'Romutoosa'.
Ongelman voi ratkaista joko sillä, että sopii synonyymien kirjaajan kanssa erityisen kantasanalistan, s.o. perusmuotoiset sanat, ja linkittää synonyymit niihin. Tämä on hyvä malli 'Tietsuli'-tyyppisten sanojen kanssa, mutta ei niin hyvä, jos pitää synonyymittää 'Ämpäri' ja 'Sanko' -sanat. Kumpikaan kun ei ole selvästi toista sanaa parempi tai oikeampi.
Toinen ratkaisutapa on tehdä hakut rekursiivisina. Eli aina kun synonyymihaku tuottaa uuden synonyymin, ohjelma lähtee hakemaan sille uusia synonyymeja. Hakun syvyys kannattaa kuitenkin rajoittaa, koska jos haetaan jotain hyvin yleistä ja paljon synonymoitua sanaa (esim viinapullo), niin haku räjähtää äkkiä käsiin..
--
Time is on My Side
>Uusien sanojen syötön pitää olla mahdollisimman nopeaa.
Yleensä tietokannat suunnitellaan niin, että haku on mahdollisimman nopeaa =)
.. saadaan tulokseksi kantoja, jotka ehkä toimivat nopeasti mutta joita on pahuksen hidas päivittää.
Tämän seurauksena niihin ei ehditä lisätä suurta määrää tietoja, jolloin lisääntyvä tietomäärä ei hidasta hakuja. Hakunopeus on siis turvattu!
Kannattaa siis ehdottomasti tehdä kantarakenteet mahdollisimman hankaliksi.
:)
No heh ;)
Tässähän on kyseessä sanasto, joten hakuja tulee tapahtumaan huomattavasti enemmän kuin tietojen lisäämisiä, joten haku nopeus tärkeempä.
Tämä on niiiin vakavaa.. :)
On siis pakko kysyä: jos optimoidaan hakunopeuden mukaan (mikä on tietty varsin järkevää), niin miten kantarakenne pitäisi silloin tehdä? Ottaen huomioon, että sanat liittyvät toisiinsa verkkomaisesti.
Yksi taulu: sanat (ID:int, SANA:varshar, SYN:int)
SYN:int on synonyymiryhmän tunnus.
Esim: Sanoilla: tietokone, tietsikka, tietsuli on sama SYN arvo, esim 666.
Kun pitää löytää synonyymit vaikka sanalle tietokone, katsotaan, mikä SYN arvo on sillä, ja haetaan kaikki sanat joilla on sama SYN arvo.