[ starter1 @ 18.04.2006. 14:12 ] @
Pocetnik sam u ovom pa sam za pocetak zelio kreirati bazu imenik u kojoj bi stavio ime,prezime i brojeve telefona.
Kreirao sam tablicu Imenik s tri polja Ime,Prezime i broj.
1. Kako mi je najlakse unijeti vrijednosti u tu tablicu?
Npr. da dodam samo
Pero Peric 123456
Ivo Ivic 234545

2. Kako da iz txt file u kojem imam
Ime Prezime Broj
Pero Peric 123456
Ivo Ivic 234545
Jozo Jozic 234567
.................................................. ..

Napunim tu bazu.
Hvala.
[ Dejan Topalovic @ 18.04.2006. 16:29 ] @
Za ovo prvo ti necu davati odgovor, jer je to osnova - hint: INSERT.

Ovo drugo mozes uraditi pomocu komande LOAD DATA.
Code:

mysql> LOAD DATA INFILE 'putanja/do/tvog/fajla/imena.txt' 
          INTO TABLE tvoja_tabela
          FIELDS TERMINATED BY '\t';

Podrazumijeva se da su ti podaci u txt fajlu razgraniceni tabulatorom i da imas tabelu 'tvoja_tabela' sa npr. poljima ime, prezime i broj.
[ starter1 @ 19.04.2006. 09:27 ] @
@ Dejan
Hvala prije svega.
Dakle ja hocu napraviti Imenik.
Kreirao sam bazu Imenik i u njoj tablicu Imenik s tri polja .
Preko phpmyadmin-a dodem do baze imenik i do sql-a i napism

LOAD DATA INFILE 'C:\imenik.txt'
INTO TABLE imenik
FIELDS TERMINATED BY '\t';

A on mi javi gresku

SQL-upit:

LOAD DATA INFILE 'C:\imenik.txt' INTO TABLE imenik FIELDS TERMINATED BY '\t';

MySQL poruka:

#29 - File 'C:imenik.txt' not found (Errcode: 2)


Pa mi nije jasno jer na C.\ imam txt file imenik.txt i u njemu
Ivica Ivic 223344
Pero Peric 112233
Proba Probic 123456
Mate Matic 123456
Darko Darkic 132345
[ starter1 @ 19.04.2006. 09:49 ] @
Evo samo da kazem da radi greska je bila u \
Dakle treba
LOAD DATA INFILE 'C:/imenik.txt'
INTO TABLE imenik
FIELDS TERMINATED BY '\t';

Dejanu se zahvaljujem jos jednom
[ Alexandar_d @ 26.08.2006. 12:14 ] @
Napokon nasao! Ovo mi je trebalo. Ali ima jedan problem. Naime, svaku rijec iz fajla treba da mi upisuje u novi red u polju "rijeci" i da u polje do "rijeci" koje se zove "naziv_fajla" upise naziv tog fajla. A ako se neka rijec ponavlja, znaci ako vec postoji u bazi pod poljem "rijeci", da je ne upisuje nego samo da "refreshuje" red "naziv_dokuemnta" do te rijeci, tako sto ce dodati naziv tog fajla od te rijeci.

Npr:

U bazi imam

------------- ----------------
rijeci naziv fajla
------------ -----------------
auto fajl1
kuca fajl 1
neboder fajl 1

I sad se unosi novi fajl sa sadrzajem: brdo i auto. Posto se brdo ne nalazi u bazi, upisuje ga ispod i pod naziv fajla stavlja "fajl2". A rijec "auto" se vec nalazi u bazi i samo treba da doda u polje "naziv fajla" pojam "fajl 2" ispod onoga sto vec postoji u tom redu, tj. "fajl 1"
Ovako bi trebala da izgleda baza nakod unosa novog fajla koji
sadrzi pojmove "auto" i "brdo"

------------- ----------------
rijeci naziv fajla
------------ -----------------
auto fajl1 fajl 2
kuca fajl 1
neboder fajl 1
brdo fajl 2

Molim vas pomozite!


[Ovu poruku je menjao Alexandar_d dana 26.08.2006. u 15:19 GMT+1]
[ Dejan Topalovic @ 26.08.2006. 19:35 ] @
Mislim da si pogresno dizajnirao strukturu tabele za tu svrhu.
Naime, sta ce se desiti nakon 100 ili 1000 izmjena? Imaces:
Citat:
auto fajl1 fajl1 fajl3 ... fajl1000

Bolje bi ti bilo da kreiras tabelu za nazive fajlova:
Code:
CREATE TABLE fajlovi (
file_id MEDIUMINT NOT NULL AUTO_INCREMENT,
naziv_fajla VARCHAR(64),
PRIMARY KEY(file_ID));

zatim tabelu za rijeci:
Code:
CREATE TABLE rijeci(
rijec_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
rijec VARCHAR(32),
PRIMARY KEY(rijec_id));

i onda povezes fajlove i rijeci jednom lookup tabelom:
Code:
CREATE TABLE rijeci_u_fajlovima (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
file_id INT UNSIGNED NOT NULL,
rijec_id INT UNSIGNED NOT NULL,
UNIQUE INDEX(file_id, rijec_id));


Ovako mozes u tabelu "rijeci" upisati koliko god zelis rijeci i povezati ih sa bilo kojim fajlom u kojem se te rijeci nalaze.

No, ako bas zelis zadrzati taj princip unosa podataka, onda ne mozes to direktno uraditi sa LOAD DATA.
Moguce rjesenje je da kreiras jednu privremenu (temporary) tabelu u koju ces unositi sadrzaj iz najnovijeg fajla, pa potom podatke iz privremene tabele unositi u ciljnu tabelu:
Code:
CREATE TEMPORARY TABLE privremena_tabela
AS SELECT * FROM originalna_tabela
WHERE 0=1;

LOAD DATA INFILE 'C:/nekifajl.txt' 
INTO TABLE privremena_tabela
FIELDS TERMINATED BY '\t';

-- pretpostavka je da si kolonu 'rijec' definisao kao PRIMARY KEY 
-- ili kao UNIQUE, nakon cega mozes izvrsiti slijedece:

INSERT INTO originalna_tabela o
SELECT * FROM privremena_tabela p
ON DUPLICATE KEY UPDATE o.naziv_fajla = o.naziv_fajla ||' '|| p.naziv_fajla;

Edit: Zasto se za tabulator ne prikazuje ispravno backslash i t, nego samo slovo t?

[Ovu poruku je menjao Dejan Topalovic dana 26.08.2006. u 20:55 GMT+1]
[ Alexandar_d @ 26.08.2006. 21:05 ] @
E drugu hvala ti puno poslusat cu te. Uradit cu tako kako si rekao. Ja sam sve ovo vec uradio ali rijeci unosim sa php skriptom, skripta cita fajl i rijec po rijec iz tog fajla upisuje u bazu. Medjutim, kada se baza napuni npr. oko SAMO 10 000 rijeci, unos u bazu novih rijeci traje predugo, cak do timeout-a. Pa me zanima, da li ce ovo raditi jako brzo bez ikakvih problema? Jer moras pretpostaviit da ce npr. u bazi biti 10 000, 20 000 pa i 1000 000 rijeci, i onda treba dodati nove rijeci. A da bi dodao novu rijec, MORA SE PROVJERITI DA LI TA RIJEC VEC POSTOJI U BAZI - znaci provjerit 1000 000 rijeci. Ako rijec postoji, samo je "refreshuje", ako ne, onda je dodaje. Jesil racunao na to?
[ Dejan Topalovic @ 26.08.2006. 21:24 ] @
Naravno da sam kontao na to. :)

Sa prvim rjesenjem imas PRIMARY KEY nad rijec_id u tabeli "rijeci" i PRIMARY KEY nad "file_id" u tabeli fajlovi, sto ti ne dopusta duplikate u tabeli. Ti prvo upises u tabelu fajlovi naziv tog fajla, pa onda iz njega izlistavas rijeci PHP-om ili mozes onako sa LOAD DATA.
U lookup tabeli takodje imas osiguranu jedinstvenost kombinacije file <=> rijec, jer imas UNIQUE index nad tim kolonama. Dakle, kada pokusas unijeti rijec iz fajla, a ta kombinacija vec postoji, insert se uopste nece dogoditi.

Kod drugog rjesenja imas INSERT ... ON DUPLICATE KEY, tako da ne moras prvo provjeravati u tabeli da li postoji ta rijec...


Ajd ti prvo isprobaj oba rjesenja, pa javi koje je brze i da li rade. :)

[ Alexandar_d @ 26.08.2006. 21:47 ] @
Naravno da cu isprobati i dati ovdje rezultate. Mislim da ce ovo jos mnogima trebati. Samo jedna sitnica. Evo kod prvog rjesenje, postoje "dvije vrste" duplikata. Jedna vrsta duplikata je npr. ako se jedna rijec u JEDNOM fajlu ponavlja vise puta. Znaci, on samo upise jedanput tu rijec, ako se javi duplikat u tom fajlu, onda samo preskoci. A druga vrsta duplikata je ako se neka rijec unosi uz fajla a ta rijec vec postoji u BAZI (unijeta prilikom unosa prijasnjeg fajla), on treba SAMO DA DODA naziv tog fajla pored onih naziva koji vec postoje.

I imas gresku u ovom codu
Code:

CREATE TABLE rijeci_u_fajlovima (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
file_id INT UNSIGNED NOT NULL,
rijec_id INT UNSIGNED NOT NULL,
UNIQUE INDEX(file_id, rijec_id));


Kaze:

#1075 - Incorrect table definition; There can only be one auto column and it must be defined as a key
[ Alexandar_d @ 27.08.2006. 13:12 ] @
Sada sam malo bolje pogledao tvoj code... Naime, stavljajuci polje ID kao primary nisi nista postigao. Jer ako je neke rijec dupla, ona ce se opet upisati u bazi samo pod razlicitim kljucem. I sta si time dobio? Opet imas duplu rijec u bazi, a jel ona pod razlicitim ID-om, to je nebitno. Sto znaci neku istu rijec mozes imati 1000 puta pod razlicitim kljucem. To je nepotrebno. Baza ne smije da ima duplikata, to samo zauzima memoriju u bazi. Dovoljno je samo jedna jedinstvena rijec, a onda u drugo polje navesti u kojem se fajlu ta rijec nalazi (kao sto sam ja gore uradio). Sto se tice brzine unosa podataka po ovom tvoj nacinu, tacno, nece biti problema oko brzine, jer on ce fakticki samo unositi rijeci nema nikakve provjere, al zato ce u bazi biti duplih rijeci. Ili ja grijesim mozda si ti nesto drugo mislio?

I kako da rijeci iz fajla unosi u jedno polje ali SVAKU RIJEC U NOVI RED? Onaj tvoj code gore unosi rijeci iz fajla i sve komptelno ih smjesta u jedan red u polje "rijeci"?
[ Dejan Topalovic @ 27.08.2006. 23:53 ] @
Eehehehe, pa lijepo sam napisao da provjeris da li rade ta rjesenja, jer sam ih pisao iz glave, dakle bez testiranja...

No, da ne kazes kako sam ti dao besmislene hintove, evo ti kompletan primjer u stilu Toma Kytea...

Za ovaj primjer sam kreirao glavnu tabelu "rijeci" i dvije privremene tabele radi prikaza funkcionisanja LOAD DATA...

Code:

C:\Dokumente und Einstellungen\Dejan>mysql -u dejan -p dejan
Enter password: *****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.24-community-nt-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE TABLE rijeci(
    -> rijec VARCHAR(30) NOT NULL,
    -> fajl VARCHAR(30),
    -> PRIMARY KEY(rijec));
Query OK, 0 rows affected (0.47 sec)

mysql> DESCRIBE rijeci;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| rijec | varchar(30) | NO   | PRI |         |       |
| fajl  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> CREATE TABLE privremena AS SELECT * FROM rijeci WHERE 0=1;
Query OK, 0 rows affected (0.53 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESCRIBE privremena;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| rijec | varchar(30) | NO   |     |         |       |
| fajl  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)


mysql> CREATE TABLE privremena2 AS SELECT * FROM rijeci WHERE 0=1;
Query OK, 0 rows affected (0.53 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESCRIBE privremena2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| rijec | varchar(30) | NO   |     |         |       |
| fajl  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> ALTER TABLE privremena2 ADD CONSTRAINT PRIMARY KEY(rijec);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESCRIBE privremena2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| rijec | varchar(30) | NO   | PRI |         |       |
| fajl  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

Uoci razliku u koloni 'Key' za tabele 'privremena' i 'privremena2'. Kasnije ces opaziti djelovanje PRIMARY kljuca.

Napravimo fajl "rijec.txt" u glavnom C: direktorijumu (C:\rijec.txt) i to sa slijedecim sadrzajem:

Code:

rijec1    fajl1
rijec2    fajl2
rijec1    fajl2
rijec2    fajl2
rijec3    fajl2
rijec4    fajl2
rijec5    fajl2
rijec1    fajl3
rijec2    fajl3
rijec1    fajl4

Napomena: Da bi koristio LOAD DATA INFILE, moras kao root zeljenom korisniku dodijeliti FILE privilegiju (kod mene je verzija 5.0.24):
Code:
mysql> GRANT FILE ON *.* TO [email protected];

Ubacimo sadrzaj tog fajla u tabelu 'privremena2' (privremena tabela sa PRIMARY kljucem):
Code:

mysql> LOAD DATA INFILE 'c:/rijec.txt' INTO TABLE privremena2 FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\r\n';
ERROR 1062 (23000): Duplicate entry 'rijec1' for key 1

mysql> select * from privremena2;
+--------+-------+
| rijec  | fajl  |
+--------+-------+
| rijec1 | fajl1 |
| rijec2 | fajl2 |
+--------+-------+
2 rows in set (0.00 sec)

Primijetices da zbog primarnog kljuca dolazi do prijavljivanja greske i da se unos prekida. Dakle, nemoguce je jednu rijec dvaput upisati u tabelu.

Sad ubacimo sadrzaj fajla u tabelu 'privremena' (privremena tabela bez PRIMARY kljuca):
Code:

mysql> LOAD DATA INFILE 'c:/rijec.txt' INTO TABLE privremena FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\r\n';
Query OK, 10 rows affected (0.00 sec)
Records: 10  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT * FROM privremena;
+--------+-------+
| rijec  | fajl  |
+--------+-------+
| rijec1 | fajl1 |
| rijec2 | fajl2 |
| rijec1 | fajl2 |
| rijec2 | fajl2 |
| rijec3 | fajl2 |
| rijec4 | fajl2 |
| rijec5 | fajl2 |
| rijec1 | fajl3 |
| rijec2 | fajl3 |
| rijec1 | fajl4 |
+--------+-------+
10 rows in set (0.00 sec)


Svi redovi iz fajla su ubaceni u tabelu.

Sad nam samo preostaje da iz te privremene tabele prebacimo sadrzaj u glavnu tabelu 'rijeci':
Code:

mysql> INSERT INTO rijeci
    -> SELECT * FROM privremena
    -> ON DUPLICATE KEY UPDATE rijeci.fajl = CONCAT(rijeci.fajl, ' ', privremena.fajl);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 5  Warnings: 0

mysql> SELECT * FROM rijeci;
+--------+-------------------------+
| rijec  | fajl                    |
+--------+-------------------------+
| rijec1 | fajl1 fajl2 fajl3 fajl4 |
| rijec2 | fajl2 fajl2 fajl3       |
| rijec3 | fajl2                   |
| rijec4 | fajl2                   |
| rijec5 | fajl2                   |
+--------+-------------------------+
5 rows in set (0.00 sec)

I nakon toga obrisemo sadrzaj privremene tabele (samo ukoliko ne koristis TEMPORARY tabelu):
Code:

mysql> DELETE FROM privremena;
Query OK, 10 rows affected (0.02 sec)

Vidis kako divno funkcionise? :)

Ali opet, rjesenje sa odvojenim tabelama je po meni daleko bolje, nego ovako da radis...


Edit: Previdio sam mogucnost, da se u nekom fajlu ponovi kombinacija rijeci i fajla, pa bi onda za jednu rijec naziv fajla mogao biti ponovljen vise puta...npr. 'rijec1 fajl1 fajl2 fajl1 fajl3 fajl4 fajl2'. Da bi se to sprijecilo, potrebno je onda staviti PRIMARY KEY na obe kolone rijec i fajl u tabeli privremena, te izmijeniti LOAD DATA izraz da bude:
Code:
mysql> LOAD DATA INFILE 'c:/rijec.txt' IGNORE INTO TABLE privremena FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\r\n';
Pri ovom uslovu, tabela 'privremena' ne smije biti na kraju ispraznjena sa 'DELETE FROM privremena'.
[ vtl_design @ 28.08.2006. 00:23 ] @
Ova ce ti sva prica pasti u vodu ako unos novih rijeci bude trajao duze od 30 sekundi :-).
Sutra budem detaljno testirao i objavim rezultate. A ako unos ne bude trajao duze od 30 sekundi, i ako pretraga tih rijeci bude manja od 6 sekundi (koliko po mom nacinu radi) i ako baza ne bude 2 ili vise puta zauzimala fizicke memorije nego sto su ti txt fajlovi koji se unose u bazi, castim te picem :-).
[ Dejan Topalovic @ 28.08.2006. 08:12 ] @
Ma ne moras ti mene castiti, nisam ja ovdje radi toga. :)

Isprobaj, vidi da li i kako radi, pa detaljno kao i ja navedi sta si i kako uradio, te koliko traje...

Sto se tice fizickog zauzeca na disku, ne znam da li moras cuvati sigurnosne kopije tih tekstualnih fajlova sa rijecima ili ne. Ako ti nakon ucitavanja rijeci i naziva fajlova ti fajlovi vise ne trebaju, onda ih mozes slobodno obrisati i time ustediti na prostoru.
U svakom slucaju, gledaj da dobijes na brzini, a zauzece diska nek ti ne predstavlja glavnu brigu...

PS: Sta ce ti dva korisnicka naloga?
[ vtl_design @ 28.08.2006. 13:25 ] @
Evo sada sam poceo da testiram i sve radi dobro do ovoga:

Code:

mysql> INSERT INTO rijeci
    -> SELECT * FROM privremena
    -> ON DUPLICATE KEY UPDATE rijeci.fajl = CONCAT(rijeci.fajl, ' ', privremena.fajl);
ERROR 1064: You have an error in your SQL syntax.  Check the manual that corresp
onds to your MySQL server version for the right syntax to use near 'ON DUPLICATE
 KEY UPDATE rijeci.fajl = CONCAT(rijeci.fajl, ' ',


Ali u tebe radi bez problema? U mene je verzija 4.0.12 MySQL-a????
[ vtl_design @ 28.08.2006. 13:26 ] @
Evo sada sam poceo da testiram i sve radi dobro do ovoga:

Code:

mysql> INSERT INTO rijeci
    -> SELECT * FROM privremena
    -> ON DUPLICATE KEY UPDATE rijeci.fajl = CONCAT(rijeci.fajl, ' ', privremena.fajl);
ERROR 1064: You have an error in your SQL syntax.  Check the manual that corresp
onds to your MySQL server version for the right syntax to use near 'ON DUPLICATE
 KEY UPDATE rijeci.fajl = CONCAT(rijeci.fajl, ' ',


Ali u tebe radi bez problema? U mene je verzija 4.0.12 MySQL-a????

A sto se tice dva accounta, ponekad me ovaj zeza nece da se loguje (mislim da je do browsera)
[ Dejan Topalovic @ 28.08.2006. 14:12 ] @
Sorry, ON DUPLICATE KEY radi tek od verzije 4.1.0, tako da ces morati uraditi upgrade ili naci neko drugo rjesenje. :)
[ Alexandar_d @ 08.09.2006. 22:32 ] @
Samo da javim da ovaj nacin koji si ti prezentarao RADI PERFEKTNO! Brzina unosa rijeci po tvom nacinu je toliko velika da nije potrebno ni mjeriti vrijeme.
Sto se tice zauzeca memorije, ni to nije toliko veliko. Ja sam se opredjelio da koristim ovaj nacin gdje nazive fajlova upisujem u susjedno polje "fajl" do "rijeci". Ti si gore spominjao da drzim odvojeno rijeci i nazive fajlova... Sta bi postigao time? Ovako sasvim OK radi. Al zanima ma razlog zasto mislis da je tako bolje i "isplatili" se to tako raditi?
Jos jedno pitanje, sada kada pretrazujem rijeci u bazi, da li je najbolje da koristim "originalni" SQL upit tipa:

Code:

SELECT *
FROM `rijeci`
WHERE `rijec` = CONVERT( _utf8 'neka_rijec'
USING latin1 )
COLLATE latin1_swedish_ci
LIMIT 0 , 30


Ili ima neko bolje rjesenje? I samo me jos zanima kako da prilagodim da mi upisuje i nasa slova š.đ,č,ć,ž? Npr. kada neka rijec u fajlu sadrzi ta slova, da je on upise u bazu sa tim slovima, da li moram promjeniti collation ili sta?