Inserire dati disordinati

Salve a tutti,

Premessa

Sto creando un sistema di voto via internet, in una tabella memorizzeroi voti ed in un'altra i log con nome utente ed azione eseguita. Ovviamente nel voto non c'e nessun riferimento all’utente che l’ha
eseguito, ma la sequenza dei log del voto einevitabilmente identica alla sequenza di votazione (esempio: l'utente che ha generato il quinto log e sempre uguale all’utente che ha eseguito il quinto voto).

Domanda

Esiste un metodo per generare un “accettabile livello di casualita`”
nella tabella dei voti? oppure inserire i nuovi dati non in coda alla
tabella.

Andrea

basta che nella tabella dei voti non metti una colonna indice e i dati
sono in ordine casuale

Andrea R. wrote:

Salve a tutti,

Premessa

Sto creando un sistema di voto via internet, in una tabella memorizzeroi voti ed in un'altra i log con nome utente ed azione eseguita. Ovviamente nel voto non c'e nessun riferimento all’utente che l’ha
eseguito, ma la sequenza dei log del voto einevitabilmente identica alla sequenza di votazione (esempio: l'utente che ha generato il quinto log e sempre uguale all’utente che ha eseguito il quinto voto).

Domanda

Esiste un metodo per generare un “accettabile livello di casualita`”
nella tabella dei voti? oppure inserire i nuovi dati non in coda alla
tabella.

Andrea

In teoria avresti ragione, ma se creo una tabella senza primary key, gli
inserisco dei dati e faccio una select, mi ritornano nello stesso ordine
in cui li ho inseriti… ho fatto una prova e l’ordine non cambia
neanche se modifico i campi quindi il problema mi rimane… se so che
una persona ha votato per quindicesima so il voto della persona.

Grazie comunque per l’idea!
Andrea

Alessandro S. wrote:

basta che nella tabella dei voti non metti una colonna indice e i dati
sono in ordine casuale

Andrea R. wrote:

Salve a tutti,

Premessa

Sto creando un sistema di voto via internet, in una tabella memorizzeroi voti ed in un'altra i log con nome utente ed azione eseguita. Ovviamente nel voto non c'e nessun riferimento all’utente che l’ha
eseguito, ma la sequenza dei log del voto einevitabilmente identica alla sequenza di votazione (esempio: l'utente che ha generato il quinto log e sempre uguale all’utente che ha eseguito il quinto voto).

Domanda

Esiste un metodo per generare un “accettabile livello di casualita`”
nella tabella dei voti? oppure inserire i nuovi dati non in coda alla
tabella.

Andrea

2010/9/23 Marco M. [email protected]:

Se invece usi l’indice ma il valore lo generi tu in maniera casuale?

Comunque, se non metti un order (almeno mysql) te li torna in ordine
cronologico.

Una (quasi) soluzione potrebbe essere quella di non usare un record
per ogni voto, ma di usare un record per ogni voto possibile e un
contatore che dice quanti l’hanno scelto. Una persona con accesso
(costante) alla db e’ ancora in grado di sapere come ha votato la
prima persona finche’ non vota la successiva (a meno che anche questa
voti nello stesso modo).

Ora mi chiedo anche io se c’e’ un modo per evitare questo problema, ma
direi che se c’e’ deve essere piuttosto complesso!

Ciao

Se invece usi l’indice ma il valore lo generi tu in maniera casuale?

2010/9/23 Luca De Marinis [email protected]:

2010/9/23 Marco M. [email protected]:

Se invece usi l’indice ma il valore lo generi tu in maniera casuale?

Comunque, se non metti un order (almeno mysql) te li torna in ordine
cronologico.

Ah, e rileggendo il post iniziale: che intendi per “loggare azione
dell’utente”? - perche’ se successivamente dovesse essere necessario
poter rispondere alla domanda dell’utente “Dammi conferma del fatto
che il sistema ha registrato il mio voto correttamente, dimmi come ho
votato”, allora ci vuole un po’ di crittografia!

Vediamo… al momento del voto potresti generare un numero casuale
abbastanza grande (x per gli amici), restituirlo all’utente, e salvare
nel log un record tipo

id:“md5(x + id_utente)” | value:“md5(x + voto_utente)” – [con +
intendo concatenazione]

(e poi “dimenticare x”, ovvero non scrivere da nessuna parte che per
quella votazione e’ stato usato quel numero!)

In questo modo, conoscendo x e l’id dell’utente sei in grado di
confermargli che il suo voto e’ stato registrato correttamente ed era
v (provando i vari voti possibili), ma una persona che abbia accesso
al db non mi sembra che sia in grado di saperlo (a meno che ovviamente
non abbia anche sniffato la comunicazione mentre veniva trasferito x!)

…il bello della crittografia e’ che ti sfugge sempre qualcosa,
quindi se ho detto qualche cazzata abbiate pieta’ :wink:

2010/9/23 Marco M. [email protected]:

Se invece usi l’indice ma il valore lo generi tu in maniera casuale?

pare anche a me la soluzione più ovvia, molti db hanno già una
funzioncina che lo fa e farlo in ruby è banale.

2010/9/23 Andrea R. [email protected]:

Domanda

Esiste un metodo per generare un “accettabile livello di casualita`”
nella tabella dei voti? oppure inserire i nuovi dati non in coda alla
tabella.

Un po’ di teoria dell’accesso concorrente dovrebbe farti dubitare
fortemente della veridicità della tua assunzione sulle sequenze
identiche, a meno che la tua applicazione non sia mono thread… :wink:
Non potresti limitarti a fare uno shuffle dei voti quando li leggi, e
fregartene di come sono ordinati sul db?

Luca De Marinis wrote:

rileggendo il post iniziale: che intendi per “loggare azione
dell’utente”? - perche’ se successivamente dovesse essere necessario
poter rispondere alla domanda dell’utente “Dammi conferma del fatto
che il sistema ha registrato il mio voto correttamente, dimmi come ho
votato”, allora ci vuole un po’ di crittografia!

L’obiettivo enon poterti dire cosa hai votato (il voto deve rimanere segreto) ma poterti dire quando hai votato. Diciamo cosi: Il fatto che hai votato euna informazione riservata, che cosa hai votato e un informazione che non voglio poter ottenere,
non si sa mai, se non posso ottenerla non possono chiedermela.

I dati che loggo (lo so e` un termine orribile) sono:

Accesso al sistema
Disconnessione dal sistema
Scadenza sessione
Esecuzione del voto

Per garanzia do la possibilita` ad ogni utente di vedere i propri log.

Andrea

gabriele renzi wrote:

2010/9/23 Marco M. [email protected]:

Se invece usi l’indice ma il valore lo generi tu in maniera casuale?

pare anche a me la soluzione pi� ovvia, molti db hanno gi� una
funzioncina che lo fa e farlo in ruby � banale.

Direi che funziona!

Ho fatto qualche prova, sulle prime mi rispondeva lo stesso ordine in
cui li inserivo es:

create table u ( id integer, n integer, primary key(id));
insert into u (id,n) values (1,1),(10,2),(100,3),(2,4),(5,5);
select * from u;
±----±-----+
| id | n |
±----±-----+
| 1 | 1 |
| 10 | 2 |
| 100 | 3 |
| 2 | 4 |
| 5 | 5 |
±----±-----+

Poi mi sono accorto di non aver inserito uno storage engines:

create table u ( id integer, n integer, primary key(id)) TYPE=innodb;
insert into u (id,n) values (1,1),(10,2),(100,3),(2,4),(5,5);
select * from u;
±----±-----+
| id | n |
±----±-----+
| 1 | 1 |
| 2 | 4 |
| 5 | 5 |
| 10 | 2 |
| 100 | 3 |
±----±-----+

quindi non devo far altro che generarmi un id pseudocasuale della
lunghezza del id es: rand(9999999999), che mi verifichi che non esista
gia` e poi inserirle.

Potrei, per perversione, dare un’occhio al motore piu adatto no so se la funzione di rollback dell'engine potrebbe essere un punto di debolezza del sistema o se e possibile risalire alla sequenza di
inserimento tramite qualche funzione del motore stesso… ma forse sto
eccedendo…

Grazie tantissime
Andrea

considera che se proprio vuoi sarà sempre possibile risalire all’ordine
di inserimento (direi che quasi tutti i db usano un sistema di
accodamento dati basato su puntatori, quindi seguendo i puntatori dal
primo all’ultimo record sai l’ordine).

Se vuoi evitare il problema devi usare un metodo di memorizzazione
diverso…
potresti creare invece che una tabella per ogni voto una tabella che
contiene un array di voti o una hash di voti e fare shuffle sull’array o
sulla hash prima di salvare.
In questo modo l’ordine è davvero casuale (in quanto ogni volta che
ricarichi la hash con Yaml ad esempio ricrei la struttura e quindi non
c’è traccia delle strutture precedenti).
In oltre non hai 200 tabelle se gestisci + voti…

2010/9/24 Alessandro S. [email protected]:

Se vuoi evitare il problema devi usare un metodo di memorizzazione
diverso…
potresti creare invece che una tabella per ogni voto una tabella che
contiene un array di voti o una hash di voti e fare shuffle sull’array o
sulla hash prima di salvare.
In questo modo l’ordine è davvero casuale (in quanto ogni volta che
ricarichi la hash con Yaml ad esempio ricrei la struttura e quindi non
c’è traccia delle strutture precedenti).

E se si rompe l’alimentatore del server mentre lo fai?? :wink:

Domanda

Esiste un metodo per generare un “accettabile livello di casualita`”
nella tabella dei voti? �oppure inserire i nuovi dati non in coda alla
tabella.

Un po’ di teoria dell’accesso concorrente dovrebbe farti dubitare
fortemente della veridicit� della tua assunzione sulle sequenze
identiche, a meno che la tua applicazione non sia mono thread… :wink:
Non potresti limitarti a fare uno shuffle dei voti quando li leggi, e
fregartene di come sono ordinati sul db?

Hai perfettamente ragione, ma ha condizione che ci siano votazioni
simultanee o almeno vicino alla simultaneita(suppongo una distanza di tempo inferiore alla procedura che inserisce il dato nel db), ma e un
caso piuttosto raro considerando il modesto numero di votanti divisi per
il tempo di votazione (massimo duemila persone), ma anche in questo caso
varierebbe soltanto la sequenza dei dati simultanei e non tutta la
sequenza, quindi nel complesso la lista risulta piuttosto affidabile.

Lo so, da una parte e` una masturbazione mentale, but I know my
chickens!

Andrea

Luca De Marinis wrote:

2010/9/24 Alessandro S. [email protected]:

Se vuoi evitare il problema devi usare un metodo di memorizzazione
diverso…
potresti creare invece che una tabella per ogni voto una tabella che
contiene un array di voti o una hash di voti e fare shuffle sull’array o
sulla hash prima di salvare.
In questo modo l’ordine � davvero casuale (in quanto ogni volta che
ricarichi la hash con Yaml ad esempio ricrei la struttura e quindi non
c’� traccia delle strutture precedenti).

E se si rompe l’alimentatore del server mentre lo fai?? :wink:

C’è un altra soluzione… ogni volta che qualcuno vota fai un postit con
il voto poi cancelli il record, ogni tanto stacchi tutti i postit dal
monitor li mescoli un pò e li riattacchi disordinatamente sul monitor :slight_smile:

A prova di guasti elettrici (ma non di incendio per cui suggerisco di
conservare ogni singolo postit in un contenitore ignifugo :slight_smile: )

2010/9/24 Alessandro S. [email protected]:

C’è un altra soluzione… ogni volta che qualcuno vota fai un postit con
il voto poi cancelli il record, ogni tanto stacchi tutti i postit dal
monitor li mescoli un pò e li riattacchi disordinatamente sul monitor :slight_smile:

A prova di guasti elettrici (ma non di incendio per cui suggerisco di
conservare ogni singolo postit in un contenitore ignifugo :slight_smile: )

E’ soggetto al camera-attack, a meno che la stanza con il monitor e i
post-it non sia in un bunker! :wink:

Scherzi a parte, i sistemi di voto elettronico sono complessi, ci
sara’ un motivo per cui (che io sappia) sono stati trovati buchi di
sicurezza o di privacy leak in qualsiasi sistema del genere!

Alessandro S. wrote:

considera che se proprio vuoi sarà sempre possibile risalire all’ordine
di inserimento (direi che quasi tutti i db usano un sistema di
accodamento dati basato su puntatori, quindi seguendo i puntatori dal
primo all’ultimo record sai l’ordine).

Verissimo, anche se non so quanto sia facile/possibile risalire dal file
alla sequenza. Comunque in teoria l’engine non dovrebbe modificare i
puntatori in base alla sua logica? Ma temo di non essere abbastanza
colto per avere certezze in tal senso.

Se vuoi evitare il problema devi usare un metodo di memorizzazione
diverso…
potresti creare invece che una tabella per ogni voto una tabella che
contiene un array di voti o una hash di voti e fare shuffle sull’array o
sulla hash prima di salvare.
In questo modo l’ordine è davvero casuale (in quanto ogni volta che
ricarichi la hash con Yaml ad esempio ricrei la struttura e quindi non
c’è traccia delle strutture precedenti).
In oltre non hai 200 tabelle se gestisci + voti…

In caso avevo pensato anche di buttarmi su qualcosa del genere… la
mia idea, se non rovavo nulla di piu` semplice, era:
salvare i voti in un file CSV, ogni volta che si aggiunge un voto,
rileggo il file, aggiungo il voto all’array importato, eseguo un ran
all’ordine, riscrivo il file.

Ma la mia paura e che potrebbero nascere problemi in caso di voti
ravvicinati:
Tutta questa procedura occupa sicuramente tempo, relativamente piccolo,
ma che puogenerare due o piu accessi simultanei al file, in quel caso
rischierei di perdere voti… dovrei creare dei semafori d’accesso,
insomma rischio di aumentare sostanzialmente la complessita, e maggior complessita = maggior rischio d’errore :smiley:

oltre che citando Luca:

E se si rompe l’alimentatore del server mentre lo fai?? :wink:

Per renderlo piu` veloce dovrei farlo lavorare senza scriverlo mai,
qualcosa tipo una variabile globale, in questo caso, penso, sarebbe
direttamente ruby a gestire gli accessi simultanei, ma non ne ho
certezza… dovrei fare qualche test concreto, comunque, ricitando Luca

E se si rompe l’alimentatore del server mentre lo fai?? :wink:

il rischio di blocco ti farebbe perdere tutta o tutte le votazione e non
solo l’ultimo voto… potrebbe essere fastidioso :slight_smile:

Andrea

2010/9/24 Alessandro S. [email protected]

c’� traccia delle strutture precedenti).

E se si rompe l’alimentatore del server mentre lo fai?? :wink:

C’è un altra soluzione… ogni volta che qualcuno vota fai un postit con
il voto poi cancelli il record, ogni tanto stacchi tutti i postit dal
monitor li mescoli un pò e li riattacchi disordinatamente sul monitor :slight_smile:

A prova di guasti elettrici (ma non di incendio per cui suggerisco di
conservare ogni singolo postit in un contenitore ignifugo :slight_smile: )

ROTFL ^ 2

Scusate ma in tutto il thread o mi sono perso io o sto per dire una
grossa
boiata, scusatemi in entrambi i casi.
Ma se quando l’utente vota, tu fai solo un UPDATE dell’aggregate e
memorizzi
sul db non ogni record con il voto, ma un record per l’aggregate dei
voti di
quell’opzione non risolvi il problema?

Che ne so qualcosa del tipo che il record della tabella voti è una cosa
del
genere

id_sondaggio
opzione: string (e qui metti che ne so A, B, C… si, no… inter,
juve…
nn so che tipo di sondaggio sia)
voti: integer

A questo punto quando un utente vota il suo voto finisce nel calderone e
non
lo tracci più (a patto di loggare anche tutte le update sul db).

Può andare o sto perdendo qualcosa?

Bacini
P


“… static analysis is fun, again!”

OWASP Orizon project leader, http://github.com/owasp-orizon
Owasp Italy R&D director

Paolo P. wrote:

2010/9/24 Alessandro S. [email protected]

Che ne so qualcosa del tipo che il record della tabella voti è una cosa
del
genere

id_sondaggio
opzione: string (e qui metti che ne so A, B, C… si, no… inter,
juve…
nn so che tipo di sondaggio sia)
voti: integer

A questo punto quando un utente vota il suo voto finisce nel calderone e
non
lo tracci più (a patto di loggare anche tutte le update sul db).

Può andare o sto perdendo qualcosa?

Bacini
P


“… static analysis is fun, again!”

OWASP Orizon project leader, http://github.com/owasp-orizon
Owasp Italy R&D director

Non e` perverso ma risorge il problema dei voti contemporanei:

Io leggo il campo, tu leggi il campo, io aggiungo il tuo voto, e tu
aggiungi il tuo voto, ma tu hai letto il campo prima che io lo scrivessi
e quando scrivi il tuo voto cancelli il mio…

Se vi interessa, e avete la pazienza per farmi scrivere qualcosa di
compiuto, vi posto anche la struttura del DB cosi` vi dico come lo sto
implementando…

Andrea

P.S. comunque dopo pranzo :slight_smile:

2010/9/24 Andrea R. [email protected]

Può andare o sto perdendo qualcosa?

Non e` perverso ma risorge il problema dei voti contemporanei:

Ok, è bello nn dare soluzioni perverse. :slight_smile:

Io leggo il campo, tu leggi il campo, io aggiungo il tuo voto, e tu
aggiungi il tuo voto, ma tu hai letto il campo prima che io lo scrivessi
e quando scrivi il tuo voto cancelli il mio…

Perché non usare una transazione?

Vote.transaction do
vote.incrementa(voce_di_voto)
done

Si può fare così dici?

Kiss kiss
GossipPaolo


“… static analysis is fun, again!”

OWASP Orizon project leader, http://github.com/owasp-orizon
Owasp Italy R&D director