Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: SQL apua musiikkitietokannan kanssa

Sivun loppuun

punppis [02.01.2011 09:00:05]

#

Minulla on tälläinen projekti, jossa olisi tarkoitus pistää koneella olevat musiikit jonkinlaiseen järjestykseen. Tällä hetkellä musiikkia on n. 190 gigatavua (30 000 kappaletta), joten tiedostojen muokkaaminen käsin on vähän liian työlästä. Tarkoitus olisi siis poistaa duplikaatit, korjata tagit sekä tehdä jokin fiksu kansiorakenne.

Tarkoitus on siis ensin muuttaa tiedot tietokantaan, jonkajälkeen korjaan tagit tietokannasta tiedostoihin sekä kopioin tiedostot paikoilleen. Kaikki muutokset siis tehdään tietokannassa, eikä tiedostoihin kosketa kuin ihan viimeiseksi.

Kaikki muut onnistunee meikäläiseltä hyvin, mutta miten saisin fiksusti asetettua kokoelmalevyjen "album artist" -kenttään "Various Artists"? Eli sellaisiin levyihin, jossa albumin nimi pysyy samana mutta artistin nimi vaihtuu.

Onnistuuko jotenkin fiksusti suoraan SQL:llä, vai pitääkö tehdä jokin koodinpätkä jonka avulla muutan inffot tietokantaan?

Antti Laaksonen [02.01.2011 11:29:42]

#

Voitko hieman selventää tietokannan rakennetta? Mitä tauluja ja kenttiä siinä on?

punppis [02.01.2011 11:38:16]

#

Unohtui kertoa tarkemmin tuosta tietokannasta. Tietokannassa ei ole kuin yksi taulu, jossa on kaikki oleelliset tiedot kipaleesta omana kenttänään.

+--------------+---------+------+-----+---------+----------------+
| Field        | Type    | Null | Key | Default | Extra          |
+--------------+---------+------+-----+---------+----------------+
| id           | int(11) | NO   | PRI | NULL    | auto_increment |
| title        | text    | YES  |     | NULL    |                |
| artist       | text    | YES  |     | NULL    |                |
| album        | text    | YES  |     | NULL    |                |
| year         | int(11) | YES  |     | NULL    |                |
| track        | int(11) | YES  |     | NULL    |                |
| disc         | int(11) | YES  |     | NULL    |                |
| bitrate      | int(11) | YES  |     | NULL    |                |
| length       | text    | YES  |     | NULL    |                |
| path         | text    | YES  |     | NULL    |                |
| album_artist | text    | YES  |     | NULL    |                |
+--------------+---------+------+-----+---------+----------------+

Tähän ongelmaanhan ei tarvita muita kuin artist ja album -kenttiä. Käytännössä pitää siis vain vertailla tekstiarvoja.

UPDATE music SET album_artist = "Various Artists" WHERE albumissa on useita artisteja

Jotain tuon tyylistä olisi hakusessa.

progo [02.01.2011 12:41:08]

#

Olen itsekin pohtinut tätä VA-ongelmaa.

Lisäongelma: joskus, mutta ei usein, löytyy useita eri albumeita, joilla on sama nimi. Siinäkös on haastetta. Purkkakeinona (ja ainoana tiedoista koottuna keinona) on tutkia, mitkä kappaleet sijaitsevat samassa hakemistossa ja näin koota VA-levyt melko luotettavasti yhteen. Ei toimi tietysti, jos kaikki on samassa hakemistossa, mutta 190 gigan musiikkikollektiosi kanssa tuskin näin pahasti on. .)

Ehkä et tarvitse itse tätä, mutta ainakin Amarok 1.4 sisältää jonkun melko hyvin toimivan logiikan tunnistamaan ja kokoamaan kokoelmalevyt yhteen. Pitäisi joku päivä vaivautua etsimään se logiikka.

Antti Laaksonen [02.01.2011 12:53:57]

#

Alikysely saattaisi olla ratkaisu ongelmaan. Kenttä "album_artist" ei ehkä ole tarpeellinen, koska sen voi selvittää muista kentistä.

Esimerkiksi seuraava kysely listaa albumit ja niiden artistit:

SELECT album a,
       IF((SELECT COUNT(DISTINCT artist) FROM music WHERE album = a) > 1,
          'Various Artists',
          artist)
FROM music
GROUP BY a

Jos haluat kuitenkin käyttää kenttää "album_artist", vastaavaa ideaa voisi ehkä soveltaa UPDATE-komennossa.

groovyb [02.01.2011 12:54:50]

#

mun on tästä hyvin vaikea löytää ongelmaa.

Ajatellaanpa eri hakuvaihtoehtoja tietokannasta

Case 1, haku esittäjän mukaan ("artist")
Case 2, haku albumin mukaan ("Album")
Case 3, haku kappaleen mukaan ("Title")
etc.

Album artist on vain extrainfoa, ei normaalisti edes hauissa käytettävä.
Yleensä tuo tosiaan on vain lisäinfoa albumista infossa. Koska jos kyseessä on tavallinen pitkäsoitto, on album_artist sama kuin artist, jos kokoelma, album_artist on "various artists". Tähän on poikkeuksena albumit, joissa joku kappale on esim duetto vierailevan laulajan kanssa.

punppis [02.01.2011 14:07:11]

#

Tuo album artist on siis soitto-ohjelmaa (foobar) varten, jotta se osaa näyttää nuo eri artistit yhden albumin alla oikein. Muutenkin hyvän tavan mukaista laittaa tageihin tuo album artist, jos albumilla on eri artisti kuin kappaleen esittäjällä (eli kokoelmalevyissä).

Tätä album artist -kenttää ei siis ole kaikkien kappaleiden id3tageissa ja haluaisin ne sinne laittaa, jotta ne näkyisivät foobarissa (ja muissa soittimissa) fiksusti.

Kenttä auttaa myös hakemistorakenteen luomisessa. Tarkoitus on rakentaa musiikkikansio seuraavanlaisella kaavalla: Artisti\[vuosi] Albumi\kappale.mp3. En halua jokaisesta yksittäisestä artistista erillistä kansiota, vaan haluan ne Various Artists kansion alle.

groovyb [02.01.2011 14:23:26]

#

Saathan sinä artistit kun teet haun Albumin mukaan, jonka jälkeen tulee listaus artisteista.

SELECT Artist FROM taulu WHERE Album = 'jotain' -> Lista artisteista

Tuo Album_Artist on vain nimellinen info, sitä ei juuri missään tarvita muuta kuin lisäinfona.

Tietenkin jos haluat tiedostolistauksen noin, voit tehdä tauluun vaikka boolean muuttujan Various_Artist, ja mikäli tämä on true, kappale löytyy Various artist kansion alta.

Käyttääkö foobar tietokantaa suoraan, ja taulu on ehdollistettu sille miten foobar sitä käsittelee?

jos näin, niin sitten on muutenkin paha lähteä muokkaamaan tietokantaa ellei foobariin voi itse muokata myös SQL kyselyjä.

Mutta enivei. Tässä itse muutos kuten halusit sen. voit tehdä sen siten että käyt läpi jokaisen albumin joka on tällä hetkellä tietokannassa, yllä olevalla komennolla.Jos Artist lukumäärä > 1, niin Various_Artist = 'Various Artists'
jos haluat suoraan numeron listan sijaan, käytä COUNT:a

1. kaikki tiedot tietokantaan
2. kannan läpikäynti albumeittain, jos artist count > 1, Various_Arist = 'Various artists'
3. Muut muutokset
4. kopiointi uusiin hakemistoihin

punppis [02.01.2011 14:42:11]

#

Siis tuo tietokanta on vaan käytössä tämän tietojen muokkauksen ajan. Teen tarvittavat muutokset tietokantaan, poistan duplikaatit ja sen jälkeen siirrän tietokannassa olevat tiedostot uuteen hakemistoon ja päivitän tagit. Tämän jälkeen poistan tietokannan ja jäljelle jääneet duplikaattitiedostot ja laitan kappaleet uudestaan foobaariin.

Ajattelin että on helpompi muokata ensin SQL-kantaan nämä muutokset, kun lähteä suoraan säätämään tiedostojen kanssa jos jokin menee pieleen.

groovyb [02.01.2011 14:49:52]

#

kova on työ, koska se edellyttää että ID3 tageihin voi luottaa. Kaikissa ei välttämättä ole mitään infoa kappaleen ja esittäjän lisäksi. Mutta tähän ei olisi kyllä tarvittu edes tietokantaa? tuntuu vaan turhalta työltä tehdä kanta jota ei aiota säilyttää.

onko jokin syy mikset kerää ensin kaikkia mp3sia taulukkoon koneelta, ja käy yksitellen läpi, keräten tagitiedot structiin -> Tarvittava tagien muokkaus -> tagien mukaan kopiointi uuteen kansioon -> struct pois muistista (tai no jos muistia on tarpeeksi niin ei tartte, ja voi käsitellä kaikki tietueet kerralla kun kaikista mp3sista on tiedot haettu) -> siirtyminen seuraavaan mp3seen joka on taulukossa -> etc.

progo [02.01.2011 14:55:14]

#

No onpa tenttausta. Tietokantojen käyttäminen on hyvää harjoitusta milloin vain, missä vain. Vielä kun käytetään idiomaattisia menetelmiä, ei se voi kovin negatiivinen kokemus olla.

groovyb [02.01.2011 14:58:43]

#

no, pistin vastauksen aikaisemmin. Saahan sitä tehdä ihan miten tykkää. Tuntuu vaan kovin työläältä keinolta. Ajattelin vain että itse työn tekijä pääsisi vähän helpommalla.

punppis [02.01.2011 16:02:40]

#

groovyb: tähän operaatioon kuuluu niin paljon muutakin kuin tämä various artist systeemi, joten tietokanta on mielestäni ainut järkevä vaihtoehto. Tietokannan avulla on helppo ajaa koodi ensin läpi ja katsoa mitä sille tapahtuu, sekä muutoksia voi tehdä askel kerrallaan. Olen moneen kertaan tässäkin huomannut, että mielestäni järkevä logiikka voi kusta filut alkuunsa.

Tässä on nyt tullut mm. sellaisia ongelmia, että joku artisti on saatettu kirjoittaa tageihin usealla eri tavalla (esim. AC/DC tai AC, DC sekä Milk Inc tai Milk Inc.). Jos olisin suoraan ajanut koodin läpi niin se olisi laittanut myös nuo AC/DC:t ja Milk Incit various artisteiksi, vaikka artisti onkin sama.

Toinen ongelma on ollut sellainen, että tein koodin joka etsii samankaltaisia artistien nimiä (suurinpiirtein sama merkkijonon pituus ja lähes saman verran samoja kirjaimia). Tässä on taas se ongelma, että arkistoissa sattuu olemaan artisteja, jotka ovat tismalleen saman pituisia ja tismalleen sama määrä kirjaimia (Kimera ja Rekami). Näitäkin ilmestyi satoja, ellei tuhansia erilaisin tyylein kirjoitettuja artistin nimiä, joten en jaksaisi käsin näitä korjata.

Ja mitä tuohon "kaikissa kappaleissa ei ole tageja", niin tarkoitus onkin laittaa tagittomat biisit omaan hakemistoonsa.

progo: miten niin idioottimaisia menetelmiä. Miten tekisit itse tehokkaammin?

groovyb [02.01.2011 16:11:32]

#

punppis, ei progo idioottimaisista puhunut, vaan idiomaattisista menetelmistä.
en ole kyllä kuullut että termiä olisi käytetty ohjelmointikielien yhteydessä.

idiomaattinen jollekin kielelle tms. ominainen, idiominomainen

idiomi jollekin kielelle tai kielimuodolle ominainen sana t. sanonta; (yksilön tai ryhmän) kielimuoto

Mutta uskoisin että progo tarkoitti sitä että kun käytetään niitä työkaluja joita hommaan ominaisesti kuuluukin käyttää, ei kokemus voi olla negatiivinen.

punppis [02.01.2011 16:16:28]

#

Tulipas jotenkin tyhmä olo kun luin tuon väärin... :E

Tagien virheellisyyden ja puutteiden takia tämä projekti taitaa olla mahdotonta tehdä ohjelmallisesti, ainakin tuo Various Artists -hommeli. Voisihan sitä tietty kokeilla sitä, että jos albumilla on monta eri artistia mutta ne on samassa kansiossa, niin laitetaan album artistiksi VA.

Edit: eipä tuokaan kyllä toimi koska pitäisi osata eritellä nuo "väärin nimetyt" artistit ja oikeasti eri artistit toisistaan. FFFUUUUUUU...

groovyb [02.01.2011 16:42:50]

#

Eihän sun tarvitse kansioista vielä tunnistusvaiheessa välittää

kun id tagit on luettu, teet tosiaan listan artisteista kun haen albumin mukaan.
JA jos artisteja on enemmän kuin yksi, asetat various_Artist = "Various artists"


ja kun rupeat tiedostoja kopioimaan, ehdollistat sen mukaan

String Various_Artist_State = SQL->GetVariousArtist(MP3_Name); // various artist tila kyseisestä mp3sta jollain metodilla minkä sitte olet tehnytkään

if(Various_Artist_State != "")
{
//Peruskansio
  Base_Address = "D:\\Music\\Various Artists\\";
}

else
{
//Peruskansio
  Base_Address = "D:\\Music\\";
}
//ja kun kopioit tiedostoja

//Kopiointiosoite
Address = Base_Address + Artist + \\ + "[" + Year + "] " + Album + "\\";

CopyToNewDir(MP3_Name,Address); // Joku funktio mikä kopioi mp3sen uuteen osoitteeseen

Mutta nyt kun tietokantaan on perustiedot lyöty, kannattaisi tehdä funktio joka hakee id:t biiseistä joissa on puuttuvia datoja. Nyt sait ID:t tietoosi riveistä jotka sun tulee käsin korjata. ja kun on korjattu, voit ohjelmallisesti päivittää idtagit. (suosittelen että lisäät kantaan osoitteen josta tällä hetkellä mp3:nen löytyy)

punppis [02.01.2011 17:22:23]

#

Mutta kun homma onkin siinä, että tietokannassa on useampia nimiä sille samalle artistille. Eli jos albumin nimi on vaikka Supersounds ja artistin oikea nimi on "The Artist", niin minulla saattaa olla tietokannassa tuo artistin nimi kirjoitettuna "The Artist", "The-Artist" tai vaikkapa "The.Artist". Tämän seurauksena softa tietenkin katsoo, että samalla albumilla on kolme eri artistia = Various Artists, vaikka todellisuudessa kyse on normaalista albumista.

Tämä on nyt se suurin ongelma, niinkuin tuossa aikaisemmassa postauksessa kyllä selitin. Myöskin aikaisemmin totesin, että näitä tämänkaltaisia artistien nimiä on satoja ellei tuhansia, niin en rupea niitä kyllä käsin korjaamaan.

progo [02.01.2011 17:56:01]

#

groovyb kirjoitti:

en ole kyllä kuullut että termiä olisi käytetty ohjelmointikielien yhteydessä.

idiomaattinen jollekin kielelle tms. ominainen, idiominomainen

idiomi jollekin kielelle tai kielimuodolle ominainen sana t. sanonta; (yksilön tai ryhmän) kielimuoto

Mutta uskoisin että progo tarkoitti sitä että kun käytetään niitä työkaluja joita hommaan ominaisesti kuuluukin käyttää, ei kokemus voi olla negatiivinen.

Minä olen kuullut vähän liiankin monesti, joten se on tarttunut käyttökieleen. Mutta minusta se on hyvä ilmaisu. Tulkitsit sen oikein: kullakin kielellä on omia erikoisvahvuuksia, joita hyvä koodaaja osaa käyttää hyödykseen. Ei kukaan esimerkiksi Haskellissa kirjoita iteratiivista silmukkaa, ja SQL-kyselyitä käpistellessä on idiomaattisinta delegoida mahdollisimman paljon tietokantamoottorille. Ja kokemus on hyvänä opetuksena positiivinen, vaikka voisi olla helpompiakin tapoja (joita en tiedä tähän hätään).

groovyb [02.01.2011 18:15:27]

#

Punppis, eli sinun on aika tutustua regexpin kiehtovaan maailmaan.

punppis [02.01.2011 18:52:30]

#

Mitenkäs tuon regexpillä korjaan kun noita artisteja voi olla kirjoitettuna ihan miten sattuu? Nuo kolme oli vain esimerkkejä. Jotkut artistien nimet saattavat olla jopa ihan väärin päin (A feat. B tai B feat. A).

groovyb [02.01.2011 19:53:04]

#

no, mutta suurimmasta osasta varmaan selviää merkkien poistolla. viivat, pilkut, hakasulut ja sen sellaset.

punppis [02.01.2011 20:09:19]

#

Mutta näihin ei ole mitään universaalia "sääntöä", jota voisi käyttää. Joihinkin nimiin kuuluu heittomerkki, joihinkin viiva jne. Käsin en millään jaksaisi ruveta säätämään :E

-tossu- [02.01.2011 20:17:04]

#

groovyb kirjoitti:

no, mutta suurimmasta osasta varmaan selviää merkkien poistolla. viivat, pilkut, hakasulut ja sen sellaset.

punppis kirjoitti:

Mutta näihin ei ole mitään universaalia "sääntöä", jota voisi käyttää. Joihinkin nimiin kuuluu heittomerkki, joihinkin viiva jne.

Jos ennen vertailua poistat nimestä kaikki muut paitsi kirjaimet ja muutat nekin pieniksi, niin sittenhän "The Artist", "The-Artist" ja "The.Artist" muuttuvat "theartist":ksi, eli samaksi esittäjäksi. Sitten vain arvot, mikä nimistä on oikea.

punppis [02.01.2011 20:31:17]

#

Mutta tuo vaatii sitä käsin säätämistä.

Grez [02.01.2011 20:33:44]

#

No ei onhan siinä nyt paljon pienemi työ jos ohjelma yhdistelee ja antaa listan mistä sitten vaan valitaan oikeat vaihtoehdot.

-tossu- [02.01.2011 20:39:41]

#

punppis kirjoitti:

Mutta tuo vaatii sitä käsin säätämistä.

Tuskin tuohon mitään täysin automaattista ratkaisua on olemassa. Onko eri tavalla nimettyjä esittäjiä niin paljon, että kestäisi kovin kauan valita niistä oikea. Jos ohjelma kysyy, mikä on oikea artistin nimi, ja antaa nuo vaihtoehdot, ei vastaamiseen mene montaa sekuntia.

Jos vielä lisäät ohjelmaan (A feat. B tai B feat. A) -säännön, niin tuskin käsin tarvitsee muutamaa minuttia enempää säätää. Tietysti artistin nimien vertaamiseen voisi käyttää jotain hienoa algoritmiä, mutta luulen, että teet tuon käsin monta kertaa siinä ajassa, mikä algoritimin koodaamiseen menisi.

punppis [02.01.2011 21:30:26]

#

Mjoo. Pitänee tehdä joku koodinpätkä joka kyselee noita vaihtoehtoja... :P

punppis [03.01.2011 07:13:52]

#

No nyt on nimiä fiksailtu. Seuraavaksi on tiedossa duplikaattien poisto. Ennenkuin lähden koodaamaan mitään, kysyn että onnistuisiko noiden duplikaattien löytäminen jotenkin fiksusti suoraan SQL:llä.

Duplikaatilla tarkoitan siis riviä, jossa on sama artisti, title sekä albumi.

Grez [03.01.2011 11:04:35]

#

Joo.

SELECT
	COUNT(id) kpl,
	artist,
	title,
	album
FROM
	music
GROUP BY
	artist,
	title,
	album
HAVING
	COUNT(id)>1

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta