ugrás a tartalomhoz

Többnyelvű blog megvalósítása

i · 2014. Feb. 1. (Szo), 18.30
Sziasztok!

Szeretném kérni a segítségeteket egy többnyelvű blog elkészítésében. Ismereteimet autodidaktaként szereztem ezért erősen hiányosnak érzem a tudásom. CMS és FW nélkül szeretném megvalósítani a blogot natív kódolással. A blog adatbázisa egyelőre így néz ki:
CREATE TABLE IF NOT EXISTS `language` (

	`id` TINYINT ( 1 ) AUTO_INCREMENT PRIMARY KEY,
	`code` CHAR ( 2 ) NOT NULL,
	`name` VARCHAR ( 10 ) NOT NULL,

) ENGINE = InnoDB DEFAULT CHARSET = utf8;

	INSERT INTO `language` ( `code`, `name` ) VALUES
		( 'HU', 'Magyar' ),
		( 'EN', 'English' );
		
CREATE TABLE IF NOT EXISTS `translate` (

	`id` SMALLINT ( 2 ) AUTO_INCREMENT PRIMARY KEY,
	`language_id` TINYINT ( 1 ) NOT NULL, -- language.id
	`code` SMALLINT ( 2 ) NOT NULL,
	`content` TEXT NOT NULL,

	FOREIGN KEY ( `language_id` ) REFERENCES `language` ( `id` )

) ENGINE = InnoDB DEFAULT CHARSET = utf8;

	INSERT INTO `translate` ( `language_id`, `code`, `content` ) VALUES
		( 1, 1, 'Első bejegyzés' ),
		( 2, 1, 'First post' ),
		( 1, 2, 'Első tartalom.' ),
		( 2, 2, 'First content.' ),
		( 1, 3, 'elso-bejegyzes' ),
		( 2, 3, 'first-post' ),
		( 1, 4, 'Második bejegyzés' ),
		( 2, 4, 'Second post' ),
		( 1, 5, 'Második tartalom.' ),
		( 2, 5, 'Second content.' ),
		( 1, 6, 'masodik-bejegyzes' ),
		( 2, 6, 'second-post' );

CREATE TABLE IF NOT EXISTS `post` (

	`id` TINYINT ( 1 ) AUTO_INCREMENT PRIMARY KEY,
	`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	`title_translate_id` SMALLINT ( 2 ) NOT NULL,
	`content_translate_id` SMALLINT ( 2 ) NOT NULL,
	`uri_translate_id` SMALLINT ( 2 ) NOT NULL

) ENGINE = InnoDB DEFAULT CHARSET = utf8;

	INSERT INTO `post` ( `title_translate_id`, `content_translate_id`, `uri_translate_id` ) VALUES
		( 1, 2, 3 ),
		( 4, 5, 6 );
A kulcsokat – FOREIGN KEY – hogyan kellene megoldani a `post` táblában? Más észrevételt is szívesen fogadok az adatbázissal kapcsolatban.

A .htaccess fájl tartalma:
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
A nyelvválasztás így néz ki:
SELECT * FROM `language`;
http://domain.tld/

A bejegyzések listája az alábbi címeken:

http://domain.tld/hu
http://domain.tld/en

Egy blog bejegyzést így lehet elérni:

http://domain.tld/hu/elso-bejegyzes
http://domain.tld/en/first-post
http://domain.tld/hu/masodik-bejegyzes
http://domain.tld/en/second-post

Hogyan kellene megírnom az SQL lekérdezéseket a bejegyzések listázásához valamint a bejegyzések megjelenítéséhez? Azért nem egyszerű a történet mert előfordulhatnak olyan bejegyzések amik nem lettek a `language` táblában található összes nyelvre lefordítva. Továbbá szeretném ha tanácsot adnátok azzal kapcsolatban is, hogy a fenti adatbázist hogyan kéne módosítanom ahhoz, hogy lehessen blog szerkesztés közben piszkozatokat is menteni és módosításkor visszalehessen keresni a módosítások előtti bejegyzések állapotait?

A bejegyzésekhez hozzászólás nem lesz. Admin felülettel sem kell most foglalkozni. A legfontosabb most az adatbázis megtervezése lenne a lekérdezésekkel.

Kérlek szépen titeket, hogy ne könyv címeket és ne linkeket küldjetek hanem konkrétan ennek a blognak a megvalósításában segédkezzetek a hozzászólásaitokkal!

Nagyon szépen köszönöm előre is mindenkinek aki időt szakít rám!
 
1

Segítség

Hidvégi Gábor · 2014. Feb. 1. (Szo), 18.39
Kérlek szépen titeket, hogy ne könyv címeket és ne linkeket küldjetek hanem konkrétan ennek a blognak a megvalósításában segédkezzetek a hozzászólásaitokkal!
Pedig szeretek linkelni, mert mind a php-hoz, mind pedig a mysql-hez kiváló dokumentáció van a neten, ha azt végigolvasnád, akkor a feladatot sikerrel tudnád abszolválni, legalábbis a technikai részét. Így ezek megkeresését rád bízom.

A felmerült kérdések megválaszolásában sokat segít, ha elképzeled, vagy ha vizuális típus vagy, le is rajzolod a programot, a táblákat és a köztük lévő összefüggéseket, így a legtöbb dolog nyilvánvalóvá válik.

Konkrétan mi az, amivel elakadtál, milyen hibaüzenetet kapsz vissza?
2

Probléma

i · 2014. Feb. 1. (Szo), 18.46
Nem tudom, hogy hogyan lenne a leglogikusabb ezt az elképzelést megvalósítani:

Továbbá szeretném ha tanácsot adnátok azzal kapcsolatban is, hogy a fenti adatbázist hogyan kéne módosítanom ahhoz, hogy lehessen blog szerkesztés közben piszkozatokat is menteni és módosításkor visszalehessen keresni a módosítások előtti bejegyzések állapotait?


A másik nagy probléma, hogy nem minden bejegyzés lesz lefordítva az összes nyelvre. Ezekhez nem tudom megírni az SQL lekérdezéseket azon az oldalakon ahol az összes bejegyzés listája látható valamint a `post` tábla létrehozásához a másodlagos kulcsokat nem tudom megírni. Túl bonyolult nekem.
3

Volt már hasonló munkám, ott

Hidvégi Gábor · 2014. Feb. 1. (Szo), 18.50
Volt már hasonló munkám, ott végül a megrendelő végzett minden fordítást, rá is ment a gatyája. Utólag belegondolva, teljesen fölösleges volt arra erőforrást áldozni, hogy minden le legyen fordítva, ugyanis a látogatók nem úgy viselkednek (általában), hogy elolvassák magyarul, aztán átváltanak angolra, végül pedig összevetik a franciával. Tehát nem kell problémát csinálni abból, ha nincs meg egy nyelven valami, egyszerűen nem kell megjeleníteni, és kész.

Továbbá szeretném ha tanácsot adnátok azzal kapcsolatban is, hogy a fenti adatbázist hogyan kéne módosítanom ahhoz, hogy lehessen blog szerkesztés közben piszkozatokat is menteni és módosításkor visszalehessen keresni a módosítások előtti bejegyzések állapotait?
Első körben erre milyen elképzelésed van?
4

Probléma

i · 2014. Feb. 1. (Szo), 19.00
Tehát nem kell problémát csinálni abból, ha nincs meg egy nyelven valami, egyszerűen nem kell megjeleníteni, és kész.


Ehhez hogyan írnád meg a lekérdezést ha csak annyit tudnál, hogy a $language_id PHP változó értéke: 'hu'?

Nem tudok bonyolult SQL lekérdezéseket írni, csak a nagyon alapokat.

Első körben erre milyen elképzelésed van?


Külön táblában kéne tárolnom őket? Ha igen, akkor még bonyolultabb a listázás ahol az összes bejegyzés látható.
5

Ahol

Hidvégi Gábor · 2014. Feb. 1. (Szo), 19.04
A kulcsszó, amit keresel: WHERE.

A másodikhoz: meg lehet egy táblával is oldani, azokat a rekordokat, amelyekben a piszkozatot tárolod, meg lehet jelölni egy extra mezővel, amit magyarul flag-nek szoktak hívni, s ezeket egyszerűen nem kell kilistázni. A kulcsszó itt is a WHERE.

Csak azért se linkelek.
6

Probléma

i · 2014. Feb. 1. (Szo), 19.12
Tegyük fel, hogy az összes magyar nyelvű bejegyzést akarom látni a http://domain.tld/hu webcímen:
$query = "SELECT * FROM `post` WHERE"; // $language_id = 1;
A `post` tábla:
`id` TINYINT ( 1 ) AUTO_INCREMENT PRIMARY KEY,
`date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`title_translate_id` SMALLINT ( 2 ) NOT NULL,
`content_translate_id` SMALLINT ( 2 ) NOT NULL,
`uri_translate_id` SMALLINT ( 2 ) NOT NULL
Hogyan? Nem értem. Nem tudok ilyen bonyolult lekérdezést írni. Ami biztos minden blog bejegyzésnél, hogy magyar nyelvű változata szerepel az adatbázisban. Ezek a magyar nyelvűek vannak lefordítva a többire.
7

SQL

i · 2014. Feb. 1. (Szo), 19.28
Szerintem rossz az elképzelésem az adatbázisom tervezésével kapcsolatban. Éppen ezért elsősorban szerintem egy tapasztalt szakembernek az újra tervezéshez kellene segítséget nyújtania, aztán jöhetnek a lekérdezések. Ez fontos lenne:

Továbbá szeretném ha tanácsot adnátok azzal kapcsolatban is, hogy a fenti adatbázist hogyan kéne módosítanom ahhoz, hogy lehessen blog szerkesztés közben piszkozatokat is menteni és módosításkor visszalehessen keresni a módosítások előtti bejegyzések állapotait?


A másik nagy probléma, hogy nem minden bejegyzés lesz lefordítva az összes nyelvre. Ezekhez nem tudom megírni az SQL lekérdezéseket azon az oldalakon ahol az összes bejegyzés listája látható


Ami biztos, hogy az URL-ből ezt PHP-vel megoldom:
// http://domain.tld/hu
$language_id = 1;
// http://domain.tld/en
$language_id = 2;
Valamint:
// http://domain.tld/hu/elso-bejegyzes
$language_id = 1;
$uri = 'elso-bejegyzes';
// http://domain.tld/en/first-post
$language_id = 2;
$uri = 'first-post';
Ez az egy oldal kész van ahol a nyelvek listája látható: http://domain.tld/
8

Éppen ezért elsősorban

Hidvégi Gábor · 2014. Feb. 1. (Szo), 19.33
Éppen ezért elsősorban szerintem egy tapasztalt szakembernek az újra tervezéshez kellene segítséget nyújtania
Ajánlom figyelmedbe a Weblaboron a fenti menüben a Munka és állás menüpontot. Ha nem tudsz rá pénzt áldozni, akkor viszont a kereső és a dokumentációk a jóbarátaid, a kulcsszavakat már megkaptad.
9

Segítségkérés

i · 2014. Feb. 1. (Szo), 20.09
Új vagyok itt a Weblaboron. Próbáltam új állásajánlatot feltenni, de még nem jelent meg. Csak moderáció után fog vagy valami hiba volt felvitelkor? Áldoznék rá pénzt, de sajnos csak keveset tudok. Árajánlatokat várok, hogy ki mennyiért tervezné újra ezt az adatbázist és írná meg a hozzátartozó lekérdezéseket. Ha valaki venné a fáradtságot és ingyen segítene, annak nagyon örülnék mert nagyon nehéz anyagi helyzetben élek. E-mail címem: nfq##kukac##euromail.hu

Szerk.: MySQL adatbázis tervezése
10

Pár tipp

coco · 2014. Feb. 1. (Szo), 20.47
Szia,

Ilyen több nyelvű blogokkal akadtam már össze, és fele annyira sem egyszerű, mint az jól esne. Többféle módon is megoldhatod, minden lehetőségednek van előnyös, és problémás oldala.

Tábla szerkezetben lehet próbálkozni nagyon összetett lekérdezésekkel, azt több idő lesz megtervezni, kitesztelni, és nehezebben lesz fejleszthető, cserébe gyorsabb lesz. A másik lehetőséged több külön lekérdezéssel csinálni meg a funkciókat. Egyszerűbb, gyorsabban tesztelhető ki, fejleszthetőbb, de a végeredmény lassabb lesz.

Ha több bejegyzés verziót akarsz menteni, kell egy adatverzió változó is. Az egyik lehetőséged, hogy elrakod mindegyik verzióját a bejegyzésnek külön-külön, ez több helyet fog foglalni, de gyorsabb lesz. A másik lehetőséged pedig, hogy csinálsz saját magadnak afféle adatváltozás leíró stringeket, mint amit az svn-ek is használnak, az munkában és kitesztelésben lesz sokkal több, lassabb is lesz, cserébe kevesebb helyet fog foglalni.

A nyelv választásnál a jelek szerint még nem jutottál el odáig, hogy akarni fogod elrakni azt is, milyen nyelven lett rögzítve a bejegyzés eredetileg. De majd eljutsz oda is.

Hogy mennyire szeretnéd kiadni külső munkába, azt nem úgy szokás megfogalmazni, hogy "kérem szépen", hanem egy számszerű összeggel, hogy cégként számla ellenében annyit érne meg neked.
13

Munka

i · 2014. Feb. 5. (Sze), 14.46
Hogy mennyire szeretnéd kiadni külső munkába, azt nem úgy szokás megfogalmazni, hogy "kérem szépen", hanem egy számszerű összeggel, hogy cégként számla ellenében annyit érne meg neked.


Őszintén szólva ez a dolog nem sokat érne meg nekem mert már lassan rá is jövök a helyes adatbázis struktúrára.

A nyelv választásnál a jelek szerint még nem jutottál el odáig, hogy akarni fogod elrakni azt is, milyen nyelven lett rögzítve a bejegyzés eredetileg. De majd eljutsz oda is.


Ez sokat segített mert szükséges lesz. Nem is gondoltam arra, hogy az eredeti nyelvű szöveget jelöljem valahogy.
11

Pár gondolat

szene · 2014. Feb. 3. (H), 19.45
A leírt db szerkezet túl van bonyolítva. Egy oszlopban tárolni különböző adatokat (cim, tartalom, url) az hibás tervezés, főleg úgy, hogy nincs egy plusz oszlop ami megkülönböztetné, hogy mi micsoda. Ha csak 2 nyelvet akarsz letárolni, akkor azt felesleges egy külön táblába kirakni, elég ha php kód szinten megvan (php tömb). Szerintem, ha az alap lekérdezések sem mennek, akkor felejtsd el, hogy verziókezelést csinálsz a postoknál, mert az csak tovább bonyolítja a dolgokat.

Tessék egy kis segítség: ilyen irányba indulj el:
http://sqlfiddle.com/#!2/9a312a/2
12

Verziókezelés

i · 2014. Feb. 5. (Sze), 14.43
Az UNIQUE `uri` azért nem jó megoldás mert ha pl. egy blog címének az 'EU' vagy az 'Ubuntu' címet adom, akkor az `uri` több nyelven is azonos lesz. Ez persze kiküszöbölhető:
SELECT * FROM post WHERE uri = 'second-post' AND language = 'en';
A verziókezelés pedig nagyon fontos. Sőt! Ez lenne a legfontosabb.
14

Verziókezelés

tlof · 2014. Feb. 5. (Sze), 16.43
Hello,

A post táblába vegyél fel még három mezőt. Az egyik legyen az aktualis, a másik pedig a verzioszam, a harmadik a csoport. Az aktuálisra tegyél egy indexet.

Az összes kiiró query-be fel kell venned, hogy csak aktualis = 1 értékü elemeket figyelje.
A verziószámba én egy timestampet raknék, és egy getmypid -el lekérdezett értéket. Igy nagyon kicsire csökkent az ütközés veszélye.
a csoport mező értéke pedig megegyezik a sorozatban elősször létrehozott elem id-javal. Igy url változáskor, bármikor tudod, hogy mely history elemek tartoznak egybe.

Minden mentéskor beszursz, egy új sort a post táblába, ami tartlmaz minden adatot. Ha valaki élesre állította az adott bejegyzést, akkor minden más az adott csoportba tartozó elemnek 0-ra rakod az aktualis értékét, a fenti elemnek meg egyre.

A fenti módszer hátránya, hogy szorgos adminokkal elég hamar össze szedhető pár 10e verziózott elem, amire később irhatsz valamilyen takaritó algoritmust.
15

Ezzel így csak az a bajom,

i · 2014. Feb. 5. (Sze), 20.09
Ezzel így csak az a bajom, hogy lesz több mező mint mondjuk cím, tartalom, címkék, képek, stb. Ha egy user csak a címet módosítja akkor minek új rekord a régi tartalommal? Csak foglalja a helyet a táblában. Szóval nem lenne érdemesebb minden mezőt külön táblában tárolni?
17

Nem érdemes minden mezőt

szene · 2014. Feb. 6. (Cs), 11.24
Nem érdemes minden mezőt külön táblába rakni, sőt azzal csak baj lesz a későbbiekben, nagyban megbonyolítja a lekérdezéseket.
18

Több tábla

tlof · 2014. Feb. 6. (Cs), 12.30
Ez olyan mértékü micro optimalizálás lenne, amivel a tárhelyen spórolsz, de mondjuk egy egyszerü post lekérdezéséhez kellene 3-4-5 join-t kellene használnod, vagy 3-4-5 lekérdezést (post title, post tartalom, post meta elemek)

Illetve mentéskor küzdhetnél, hogy minden mezőröl megállapitsd, hogy változott -e.

Itt a mentéskori ellenörzés könnyü. Az aktuális mezőihez egy szimpla == müvelettel összehasonlítod, ha van valamelyik mezőnél eltérés beszúrsz egy új sort, ha nincs, akkor nem csinálsz semmit.

A rengeteg redundánsan tárolt adat az adatbázisban, nem okoz gondot. Mentéskor figyelhetsz arra, hogy törölsz a db-ből (pl a 30 napnál régebbi verziókat törlöd, vagy az utolsó 20 verziót tartod csak meg). éjszaka pedig egyszer nyomsz cron-ból egy optimize-t a táblára, hogy úgy érezd mindent megtettél.
16

A unique indexbe több mezőt

szene · 2014. Feb. 6. (Cs), 11.19
A unique indexbe több mezőt is bevehetsz. Pl.: uri, language, version