<br><br><div class="gmail_quote">2009/7/8 Eden Cardim <span dir="ltr"><<a href="mailto:edencardim@gmail.com">edencardim@gmail.com</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
2009/7/8 <<a href="mailto:claudio@dpreferencial.com.br">claudio@dpreferencial.com.br</a>>:<br>
<div class="im">> Eu trabalho com processamento de pesquisas de mercado. (tabulação)<br>
><br>
> No começo trabalhei muito anos com Statiscs SPSS, Statiscs ... (com estes<br>
> programas as bases ficavam realmente gigantes..rsrs..200.000 campos..rsrs)<br>
> acabei desenvolvendo meu próprio sistema de tabulação.<br>
</div><div class="im">> levando em consideração que:<br>
> - 80% dos campos de uma pesquisa são campos numéricos e RM (respostas<br>
> múltiplas=campos multivalorados)<br>
> Ex:<br>
> Quais frutas vc gosta:<br>
> 1 - abacaxi<br>
> 2 - Mamão<br>
> 3 - abacate.... até o código 50.<br>
><br>
> um fulano responde os códigos 2/3/4/9/10/15<br>
><br>
> num buffer(array de boleanos) eu marco true nestas posição e gravo.<br>
><br>
> Veja, no SPSS ou em outras bases "normais" eu precisaria de 15 campos para<br>
> guardar as informações,<br>
> quando que eu guardo num campo só..de tamanho bem pequeno...rsrs..<br>
<br>
</div>Bom, até aqui, não vejo porque numa base relacional você precisaria de<br>
15 campos, se tivesse um modelo adequado ao seu problema como esse, em<br>
PostgreSQL:<br>
<br>
CREATE SEQUENCE person_no_seq INCREMENT BY 1 START WITH 1;<br>
CREATE SEQUENCE question_no_seq INCREMENT BY 1 START WITH 1;<br>
CREATE SEQUENCE field_no_seq INCREMENT BY 1 START WITH 1;<br>
<br>
CREATE TABLE person ( id INTEGER DEFAULT nextval('person_no_seq')<br>
PRIMARY KEY, name TEXT NOT NULL);<br>
CREATE TABLE question ( id INTEGER DEFAULT nextval('question_no_seq')<br>
PRIMARY KEY, query TEXT NOT NULL);<br>
CREATE TABLE field ( id INTEGER DEFAULT nextval('field_no_seq')<br>
PRIMARY KEY, name TEXT NOT NULL);<br>
CREATE TABLE answer ( question_id INTEGER REFERENCES question(id),<br>
field_id INTEGER REFERENCES field(id), person_id INTEGER REFERENCES<br>
person(id), UNIQUE(question_id, field_id, person_id) );<br>
<br>
INSERT INTO answer (question_id, field_id, person_id) VALUES ((SELECT<br>
id FROM question WHERE query = 'Qual a fruta que você mais gosta?'),<br>
(SELECT id FROM field WHERE name = ''), (SELECT id FROM person WHERE<br>
name = 'Solli'));<br>
INSERT INTO answer (question_id, field_id, person_id) VALUES ((SELECT<br>
id FROM question WHERE query = 'Qual a fruta que você mais gosta?'),<br>
(SELECT id FROM field WHERE name = 'Abacaxi'), (SELECT id FROM person<br>
WHERE name = 'Solli'));<br>
INSERT INTO answer (question_id, field_id, person_id) VALUES ((SELECT<br>
id FROM question WHERE query = 'Qual a fruta que você mais gosta?'),<br>
(SELECT id FROM field WHERE name = 'Uva'), (SELECT id FROM person<br>
WHERE name = 'Solli'));<br>
INSERT INTO answer (question_id, field_id, person_id) VALUES ((SELECT<br>
id FROM question WHERE query = 'Qual a fruta que você mais gosta?'),<br>
(SELECT id FROM field WHERE name = 'Mamão'), (SELECT id FROM person<br>
WHERE name = 'Wesley'));<br>
INSERT INTO answer (question_id, field_id, person_id) VALUES ((SELECT<br>
id FROM question WHERE query = 'Qual a fruta que você mais gosta?'),<br>
(SELECT id FROM field WHERE name = 'Uva'), (SELECT id FROM person<br>
WHERE name = 'Wesley'));<br>
<br>
A partir daqui você pode fazer várias consultas:<br>
<br>
Por exemplo, tendo o nome da pessoa descobrir quais frutas ela gosta:<br>
<br>
SELECT <a href="http://f.name" target="_blank">f.name</a> FROM field f JOIN answer a ON a.field_id = <a href="http://f.id" target="_blank">f.id</a> JOIN<br>
question q ON a.question_id = <a href="http://q.id" target="_blank">q.id</a> JOIN person p on a.person_id = <a href="http://p.id" target="_blank">p.id</a><br>
WHERE <a href="http://p.name" target="_blank">p.name</a> = 'Wesley' AND q.query = 'Qual a fruta que você mais<br>
gosta?';<br>
SELECT <a href="http://f.name" target="_blank">f.name</a> FROM field f JOIN answer a ON a.field_id = <a href="http://f.id" target="_blank">f.id</a> JOIN<br>
question q ON a.question_id = <a href="http://q.id" target="_blank">q.id</a> JOIN person p on a.person_id = <a href="http://p.id" target="_blank">p.id</a><br>
WHERE <a href="http://p.name" target="_blank">p.name</a> = 'Solli' AND q.query = 'Qual a fruta que você mais<br>
gosta?';<br>
SELECT <a href="http://f.name" target="_blank">f.name</a> FROM field f JOIN answer a ON a.field_id = <a href="http://f.id" target="_blank">f.id</a> JOIN<br>
question q ON a.question_id = <a href="http://q.id" target="_blank">q.id</a> JOIN person p on a.person_id = <a href="http://p.id" target="_blank">p.id</a><br>
WHERE <a href="http://p.name" target="_blank">p.name</a> = 'Mantovani' AND q.query = 'Qual a fruta que você mais<br>
gosta?';<br>
<br>
E tem um "macete" para "tabular" campos inseridos na tabela "field",<br>
você faz uma pré-consulta:<br>
<br>
SELECT <a href="http://f.name" target="_blank">f.name</a> FROM field f JOIN answer a ON a.field_id = <a href="http://f.id" target="_blank">f.id</a> JOIN<br>
question q ON a.question_id = <a href="http://q.id" target="_blank">q.id</a> WHERE q.query = 'Qual a fruta que<br>
você mais gosta?' GROUP BY <a href="http://f.name" target="_blank">f.name</a>;<br>
<br>
Depois usa os valores de retorno para construir outra consulta:<br>
<br>
SELECT <a href="http://p.name" target="_blank">p.name</a>,<br>
SUM((SELECT CASE WHEN <a href="http://f.name" target="_blank">f.name</a> = 'Mamão' THEN 1 ELSE 0 END)) AS Mamão,<br>
SUM((SELECT CASE WHEN <a href="http://f.name" target="_blank">f.name</a> = 'Abacate' THEN 1 ELSE 0 END)) AS Abacate,<br>
SUM((SELECT CASE WHEN <a href="http://f.name" target="_blank">f.name</a> = 'Abacaxi' THEN 1 ELSE 0 END)) AS Abacaxi,<br>
SUM((SELECT CASE WHEN <a href="http://f.name" target="_blank">f.name</a> = 'Maçã' THEN 1 ELSE 0 END)) AS Maçã,<br>
SUM((SELECT CASE WHEN <a href="http://f.name" target="_blank">f.name</a> = 'Uva' THEN 1 ELSE 0 END)) AS Uva<br>
FROM field f JOIN answer a ON a.field_id = <a href="http://f.id" target="_blank">f.id</a> JOIN person p ON<br>
a.person_id = <a href="http://p.id" target="_blank">p.id</a><br>
GROUP BY <a href="http://p.name" target="_blank">p.name</a>;<br>
name | mamão | abacate | abacaxi | maçã | uva<br>
-----------+-------+---------+---------+------+-----<br>
Wesley | 1 | 0 | 0 | 0 | 1<br>
Solli | 1 | 0 | 1 | 0 | 0<br>
Mantovani | 1 | 0 | 0 | 0 | 0<br>
<br>
Claro que o modelo pode ser mais preciso e elaborado, mantive simples<br>
apenas para facilitar a ilustração. As demais consultas ficam como<br>
exercício para o leitor... ;)<br>
<div class="im"><br>
> Desenvolvi um formato para o meu arquivo de dados,<br>
> levando em consideração minhas necessidades, tais como:<br>
><br>
> - conteúdo criptografado.<br>
<br>
</div>Se for criptografia da boa, você vai sofrer muito com o desempenho, e<br>
se for da criptografia ruim (xor, etc.), não vale a pena usar.<br>
Geralmente, só se criptografam dados que trafegam em locais públicos e<br>
mesmo assim, segurança é trabalho pro SO e não pro banco de dados.<br>
<div class="im"><br>
> - tamanho final do arquivo de base.<br>
<br>
</div>Economizar espaço vai fazer você gastar processamento, para<br>
"empacotar" e "desempacotar" os dados. Geralmente é preferível<br>
economizar no processamento porque espaço sempre escala, mas<br>
processamento não.</blockquote><div><br><span style="font-family: courier new,monospace;">... certamente storage é mais escalável do que processador, mas as operações de join e agrupamento de banco de dados também tem consumo de cpu considerável. Sei do teu 'fetiche' por banco de dados, mas colocar tudo dentro de um banco de dados não é garantia de desempenho (mas gostei da tua abordagem) .... </span><br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
<div class="im"><br>
> - quantidade final de campos na base.<br>
> - base não normalizada = campos multivalorados e dependentes..<br>
> - conteúdo dos campos: numérico.<br>
<br>
</div>Irrelevante com um modelo relacional adequado.<br>
<br>
Além disso, com uma base de dados relacional de verdade você vai obter<br>
vantagens como garantia de integridade, controle de concorrência,<br>
índices, etc, etc.<br>
<br>
Talvez eu não esteja enxergando direito, mas não vejo necessidade de<br>
se implementar um sistema de armazenamento próprio com os requisitos<br>
que você postou aqui a não ser por motivos educacionais.<br>
<font color="#888888"><br>
--<br>
</font><div class="im"> Eden Cardim Need help with your Catalyst or DBIx::Class project?<br>
Code Monkey <a href="http://www.shadowcat.co.uk/catalyst/" target="_blank">http://www.shadowcat.co.uk/catalyst/</a><br>
Shadowcat Systems Ltd. Want a managed development or deployment platform?<br>
<a href="http://edenc.vox.com/" target="_blank">http://edenc.vox.com/</a> <a href="http://www.shadowcat.co.uk/servers/" target="_blank">http://www.shadowcat.co.uk/servers/</a><br>
_______________________________________________<br>
</div><div><div></div><div class="h5">SaoPaulo-pm mailing list<br>
<a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>"o animal satisfeito dorme". - Guimarães Rosa<br>