Re: [pgbr-geral] Res: Uso de Campos Padrões
Bom dia a Todos! Apesar de ter fugido da minha dúvida inicial que era somente como USAR campos padrões no Postgres acabou se tornando uma Discussão muito produtiva a respeito de conceitos e idéias de diferentes partes. Agradeço à todos que responderam, e opinaram a respeito e também informo que já estou utilizando tais campos em minhas aplicação e até agora (em homologação) está funcionando conforme o esperado. Atenciosamente, Eder Sousa On Fri, 1 Jan 2010 16:27:56 -0200, Tarcísio Sassara sassara.tarci...@gmail.com wrote: Realmente gosto disto que está ocorrendo aqui. Faz valer o nome deste lugar: Lista de discussão. Segue a minha contribuição: Simplesmente não gosto do estado NULL para o valor de um atributo de uma Relação. Usar ou permitir valores nulos para um atributo é uma péssima idéia e pode causar grandes problemas. Podemos ignorar completamente este estado e definir para cada atributo um valor padrão. O uso das chaves artificiais cresceu muito com a adoção de Frameworks e seus ORMs. Inegavelmente o uso destas ferramentas simplificam o desenvolvimento de sistemas mas afastam os desenvolvedores das teorias que fundaram o SGBD que hoje utilizamos. Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. Alias, ORM não são muito legais. Até o David disse: Stop trying to generate SQL. [1]. Acredito na importância de se estudar os trabalhos dos conhecidos pesquisadores neste assunto (e que até possuem idéias diferentes) como Date e Celko. Não que as idéias destes devessem ser aplicada à risca, pois, cada caso é um caso. É importante conhecer as ferramentas que temos a disposição e as diferentes maneiras com as quais podemos solucionar um problema. Podemos fixar um prego na parede com uma chave de fenda apesar de ser muito mais simples com um martelo. E tendo um martelo é possível usar o cabo ou a cabeça... É o uso da ferramenta, mais a técnica usada de forma apropriada que faz a diferença e torna o trabalho mais simples e bem feito. Se focarmos nas teorias, usaríamos mais as chaves naturais que podemos encontrar em uma Relação. Mas existem situações em que precisamos usar as chaves artificiais. Quando nossa regra de negócio permite inserir um registro antes mesmo de se ter a chave natural completa. Por exemplo: script type=text/javascript src=http://www.softpira.com/homemail/program/js/tiny_mce/themes/advanced/langs/pt.js;/scriptNo caso da locadora de vídeos. Se for possível reservar um filme sem necessariamente especificar para quem, ou seja, apenas queremos indicar que um filme está reservado para alguém, a chave natural não estaria completa pois a chave natural da Relação Reserva inclui uma referência para o cliente que quer o filme e que neste caso não está preenchida. Pode aqui estar um exemplo de uso do NULL, onde o código do cliente é indefinido. Mas como escrevi logo acima, podemos esquecer dos valores nulos e usar valores defaults o que na minha opinião é a melhor alternativa. Então, neste exemplo, a Relação Reserva precisaria ter uma chave artificial identificando uma reserva sem mesmo ter a informação do cliente que reservou o filme. Apesar de existir algumas vantagens no uso das chaves naturais como por exemplo a não necessidade de se criar uma nova coluna para uma outra chave ou a melhor representação de acordo com o Domínio, na prática, uso muito as chaves artificiais e as chaves candidatas naturais se tornam únicas e não nulas. Tornando as chaves naturais unicas e não nulas, elimina-se o problema da duplicidade que pode ocorrer usando chaves artificiais sem tratar as naturais como no exemplo: cd_pessoa | nome --- 1 | João 2 | João Chaves artificiais simplificam as queries ad hoc quando é preciso fazer os joins e torna possível o uso dos ORMs. Um exemplo de Relação usando uma chave artificial e tratando a natural: CREATE TABLE pessoas ( cd_pessoa serial PRIMARY KEY, nome CHARACTER VARYING NOT NULL DEFAULT 'não especificado', cpf CHARACTER VARYING NOT NULL UNIQUE ); Quando criamos uma restrição de unicidade, automaticamente criamos um índice para a propriedade da relação. Isso acontece porque no momento da inserção de uma nova tupla, o SGBD pesquisa por uma ocorrência do valor que se quer inserir na Relação. Caso não encontrado, o valor é inserido. O índice ajuda nesta pesquisa. Este comportamento é ótimo pois normalmente, também usamos esta propriedade para fazer as buscas de dentro do nosso sistema. Referências: http://books.google.com.br/books?id=y_eVBB5qdwMCprintsec=frontcover#v=onepageq=f=false http://en.wikipedia.org/wiki/Natural_key [1] http://people.planetpostgresql.org/dfetter/index.php?/archives/40-Removing-Much-of-the-Suck-from-ORMs.html ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Realmente gosto disto que está ocorrendo aqui. Faz valer o nome deste lugar: Lista de discussão. Segue a minha contribuição: Por exemplo: No caso da locadora de vídeos. Se for possível reservar um filme sem necessariamente especificar para quem, ou seja, apenas queremos indicar que um filme está reservado para alguém, a chave natural não estaria completa pois a chave natural da Relação Reserva inclui uma referência para o cliente que quer o filme e que neste caso não está preenchida. Pode aqui estar um exemplo de uso do NULL, onde o código do cliente é indefinido. Mas como escrevi logo acima, podemos esquecer dos valores nulos e usar valores defaults o que na minha opinião é a melhor alternativa. Até nesse exemplo, o campo NULL pode ser evitado, bastaria reservar o filme para a própria locadora, ou seja, a locadora tb seria um cliente. Mauricio Cassemiro ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. php: doctrine, propel; python: SQLAlchemy; ruby: DataMapper; java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Abraço! -Leo -- Leonardo Cezar http://www.aslid.org.br http://postgreslogia.wordpress.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Índices e otimização
Boa tarde pessoal! andei fazendo uns testes com índices no Postgres, e não obtive diferença alguma em usar ou não índices. veja: tabela 1 (tb1): - idtb1: bigserial PK - nome: varchar(20) tabela 2 (tb2): - idtb2: bigserial PK - idtb1: bigint - sobre: varchar(20) -- 1 - inseri 30 registros em tb1 e em seguida inseri 60 registros em tb2 com idtb1 = 2; 2 - Fiz o select abaixo e gastou aprox. 12 segundos: select * from tb2 WHERE idtb1 = 2; 3 - criei o índice: CREATE INDEX tb2_idx ON public.tb2 USING BTREE (idtb1); 4 - fiz o select (item 2) novamente e gatou também aprox. 12 segundos. Fiz este mesmo teste mais de 30 vezes, e o resultado foi praticamente o mesmo. Agora a pergunta: Fiz alguma coisa de errado ou índice que coloquei não serve para nada? desde já obrigado. -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26994726.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Res: Res: Uso de Campos Padrõe s
Caro Leonardo; O hibernate NÃO é baseado no JPA. Na realidade, e o contrário! E você poderia me explicar o porquê da porcaria? A empresa para a qual trabalho (já vou avisando que sou DBA, e não trabalho com Java) está para adotar a JPA. Quais seriam as vantagens ou desvantagens do mesmo? No aguardo, Márcio de Figueiredo Moura e Castro De: Leonardo Cezar lhce...@gmail.com Para: Comunidade PostgreSQL Brasileira pgbr-geral@listas.postgresql.org.br Enviadas: Sábado, 2 de Janeiro de 2010 15:02:53 Assunto: Re: [pgbr-geral] Res: Uso de Campos Padrões 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. php: doctrine, propel; python: SQLAlchemy; ruby: DataMapper; java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Abraço! -Leo -- Leonardo Cezar http://www.aslid.org.br http://postgreslogia.wordpress.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral Veja quais são os assuntos do momento no Yahoo! +Buscados http://br.maisbuscados.yahoo.com___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Re s: Índices e otimização
desculpe, esqueci de colocar a versão do PGSQL. a versão é 8.3, uso postgres Studio, no windows 7 obrigado. MARCIO CASTRO-2 wrote: Cara colega: Você regerou as estatísticas após criar os índices? Qual é a versão do banco? No aguardo, Márcio de Figueiredo Moura e Castro -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26994863.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Res: Re s: Índices e otimiza ção
Ok; mas as estatísticas foram regeradas? De: moisespsena moisesps...@gmail.com Para: pgbr-geral@listas.postgresql.org.br Enviadas: Sábado, 2 de Janeiro de 2010 15:31:26 Assunto: Re: [pgbr-geral] Re s: Índices e otimização desculpe, esqueci de colocar a versão do PGSQL. a versão é 8.3, uso postgres Studio, no windows 7 obrigado. MARCIO CASTRO-2 wrote: Cara colega: Você regerou as estatísticas após criar os índices? Qual é a versão do banco? No aguardo, Márcio de Figueiredo Moura e Castro -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26994863.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral Veja quais são os assuntos do momento no Yahoo! +Buscados http://br.maisbuscados.yahoo.com___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Índices e otimização
Como assim as estatísticas? Tem pouco tempo que mexo com o postgres, e ainda não tenho um conhecimento aprofundado. obrigado MARCIO CASTRO-2 wrote: Ok; mas as estatísticas foram regeradas? -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26995037.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Res: Índices e otimização
Moises; Não tenho acesso ao Postgres de onde eu estou agora, mas vou tentar exemplificar. O banco de dados requer algumas informações sobre as tabelas do sistema, como a quantidade de linhas destas. Tal informação é utilizada por um componente do banco de dados que verifica o melhor caminho para acessar os dados solicitados em uma query. Se eu não me engano, via PGAdmin, você pode clicar em uma tabela com o botão direito, onde aparecerá um menú. Selecione maintenance, e clique em FULL e depois em OK. Após o mesmo, passe a query para gente dar uma olhada, ok? No aguardo, Márcio de Figueiredo Moura e Castro De: moisespsena moisesps...@gmail.com Para: pgbr-geral@listas.postgresql.org.br Enviadas: Sábado, 2 de Janeiro de 2010 15:51:59 Assunto: Re: [pgbr-geral] Índices e otimização Como assim as estatísticas? Tem pouco tempo que mexo com o postgres, e ainda não tenho um conhecimento aprofundado. obrigado MARCIO CASTRO-2 wrote: Ok; mas as estatísticas foram regeradas? -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26995037.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral Veja quais são os assuntos do momento no Yahoo! +Buscados http://br.maisbuscados.yahoo.com___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Re s: Índices e otimização
ok, Vou fazer aqui e te respondo em seguida MARCIO CASTRO-2 wrote: Moises; Não tenho acesso ao Postgres de onde eu estou agora, mas vou tentar exemplificar. O banco de dados requer algumas informações sobre as tabelas do sistema, como a quantidade de linhas destas. Tal informação é utilizada por um componente do banco de dados que verifica o melhor caminho para acessar os dados solicitados em uma query. Se eu não me engano, via PGAdmin, você pode clicar em uma tabela com o botão direito, onde aparecerá um menú. Selecione maintenance, e clique em FULL e depois em OK. Após o mesmo, passe a query para gente dar uma olhada, ok? No aguardo, Márcio de Figueiredo Moura e Castro -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26995171.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Re s: Índices e otimização
Bem, cliquei com o botão direito em cima da tabela e apareceu uma janela com as opçoes: VACUM, ANALYSE, REINDEX. Marquei a opção VACUM e logo abaixo novas opções apareceram: FULL, FREEZE e ANALYSE, marquei todas elas e mandei executar, em seguida, tive a seguinte saída na aba 'mensagens' localizada na parte inferior da janela: INFO: vacuuming public.tb2INFO: tb2: found 0 removable, 71 nonremovable row versions in 5834 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 56 to 62 bytes long. There were 0 unused item pointers. Total free space (including removable row versions) is 52116 bytes. 0 pages are or will become empty, including 0 at the end of the table. 1 pages containing 5448 free bytes are potential move destinations. CPU 0.12s/0.31u sec elapsed 1.08 sec.INFO: index tb2_pkey now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.03s/0.00u sec elapsed 0.03 sec.INFO: index tb2_idx now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.01s/0.01u sec elapsed 0.03 sec.INFO: tb2: moved 0 row versions, truncated 5834 to 5834 pages DETAIL: CPU 0.00s/0.00u sec elapsed 0.02 sec. INFO: analyzing public.tb2INFO: tb2: scanned 3000 of 5834 pages, containing 360001 live rows and 0 dead rows; 3000 rows in sample, 700082 estimated total rowsTempo total de execução da consulta: 1289 ms. -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26995234.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Eliminar Conexões Perdidas
Olá, Fabrízio 2009/12/31 Fabrízio de Royes Mello fabriziome...@gmail.com Pessoal, Estou sofrendo com um problema de algumas conexões ficarem ativas com o PostgreSQL após uma queda de energia onde todos os clientes foram desligados e o servidor, por estar ligado a um nobreak não caiu, e com isso ao ser restabelecida a energia elétrica (o servidor não foi reiniciado) as estações começam a conectar novamente, só que como já tem conexões ativas (que ficaram perdidas após a queda de energia) acaba estourando o max_connections com as novas conexões... Diante disso gostaria de trocar algumas idéias (ou se existe uma solução pronta que eu desconheça fico agradecido) pois pensei em criar algum script que verifique o client_addr e o client_port da pg_stat_activity e verificar o status do socket no sistema operacional com o netstat, e caso ele não esteja como ESTABELECIDO efetuar a eliminacao do processo... Essa é uma alternativa viável ou existe alguma forma mais elegante de contornar isso?? Esta seria uma forma de vocês fazer. O PostgreSQL tem alguns parâmetros que você pode configurar encerrar conexões IDLE, que é o caso que me parece. Os parâmetros são: tcp_keepalives_idle, tcp_keepalives_interval e tcp_keepalives_count. Sistema Operacional: Windows 2003 Versão do PostgreSQL: 8.2.14 -- Fabrízio de Royes Mello Blog sobre TI: http://fabriziomello.blogspot.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral []s -- JotaComm http://jotacomm.wordpress.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/2 Leonardo Cezar lhce...@gmail.com: 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. php: doctrine, propel; python: SQLAlchemy; ruby: DataMapper; java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Abraço! Opá, Da lista conheço o SQLAlchemy, o Propel e o Doctrine. Acho que o Doctrine superou o Propel. E no site do Doctrine diz: Avoid composite keys http://www.doctrine-project.org/documentation/manual/2_0/en/best-practices#avoid-composite-keys Se da o suporte mas não recomenda o uso, não é legal. O ORM provido pelo Django também não faz direito (faz tempo que não dou uma olhada). Para novas aplicações criadas isso não é muito problemático. É só seguir as convenções, mas quando é preciso migrar deve dar uma dor de cabeça. -- Tarcisio F. Sassara ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Índices e otimização
Olá, 2010/1/2 moisespsena moisesps...@gmail.com Boa tarde pessoal! andei fazendo uns testes com índices no Postgres, e não obtive diferença alguma em usar ou não índices. veja: tabela 1 (tb1): - idtb1: bigserial PK - nome: varchar(20) tabela 2 (tb2): - idtb2: bigserial PK - idtb1: bigint - sobre: varchar(20) -- 1 - inseri 30 registros em tb1 e em seguida inseri 60 registros em tb2 com idtb1 = 2; 2 - Fiz o select abaixo e gastou aprox. 12 segundos: select * from tb2 WHERE idtb1 = 2; 3 - criei o índice: CREATE INDEX tb2_idx ON public.tb2 USING BTREE (idtb1); 4 - fiz o select (item 2) novamente e gatou também aprox. 12 segundos. Fiz este mesmo teste mais de 30 vezes, e o resultado foi praticamente o mesmo. Agora a pergunta: Fiz alguma coisa de errado ou índice que coloquei não serve para nada? Qual o resultado do comando EXPLAIN select * from tb2 WHERE idtb1 = 2; Qual a versão do seu PostgreSQL? Você pode colocar aqui a definição da tabela? Veja o meu exemplo: Criação da tabela. postgres=# CREATE TABLE tab1(codigo INTEGER); CREATE TABLE Inserção de registros. postgres=# INSERT INTO tab1 VALUES (generate_series(1,60)); INSERT 0 60 postgres=# SELECT count(*) FROM tab1; count 60 (1 row) postgres=# SELECT * FROM tab1 WHERE codigo=500; codigo 500 (1 row) Time: 71,537 ms --Tempo da execução da consulta. postgres=# postgres=# EXPLAIN SELECT * FROM tab1 WHERE codigo=500; QUERY PLAN Seq Scan on tab1 (cost=0.00..10155.00 rows=1 width=4) Filter: (codigo = 500) (2 rows) Time: 0,643 ms --Tempo da execução do comando EXPLAIN. Adição de uma PK. Ao fazer isso automaticamente um índice será criado. postgres=# ALTER TABLE tab1 ADD PRIMARY KEY(codigo); NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index tab1_pkey for table tab1 ALTER TABLE postgres=# postgres=# SELECT * FROM tab1 WHERE codigo=500; codigo 500 (1 row) Time: 0,851 ms --Tempo da execução da consulta. postgres=# EXPLAIN SELECT * FROM tab1 WHERE codigo=500; QUERY PLAN -- Index Scan using tab1_pkey on tab1 (cost=0.00..8.33 rows=1 width=4) Index Cond: (codigo = 500) (2 rows) Time: 1,391 ms --Tempo da execução do comando EXPLAIN. Faça este teste e se o resultado for diferente do apresentado aqui, poste o seu resultado. desde já obrigado. -- View this message in context: http://old.nabble.com/%C3%8Dndices-e-otimiza%C3%A7%C3%A3o-tp26994726p26994726.html Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral []s -- JotaComm http://jotacomm.wordpress.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Re s: Índices e otimização
Moises, Criar um índice não garante que este vai ser utilizado. O PostgreSQL usa as estatiscas para saber qual a melhor forma de buscar os registros no banco. Por isso a dica de fazer um analize e regerar as estatísticas. Para garantir que o PostgreSQL fará a melhor escolha. 2010/1/2 moisespsena moisesps...@gmail.com: Bem, cliquei com o botão direito em cima da tabela e apareceu uma janela com as opçoes: VACUM, ANALYSE, REINDEX. Marquei a opção VACUM e logo abaixo novas opções apareceram: FULL, FREEZE e ANALYSE, marquei todas elas e mandei executar, em seguida, tive a seguinte saída na aba 'mensagens' localizada na parte inferior da janela: INFO: vacuuming public.tb2INFO: tb2: found 0 removable, 71 nonremovable row versions in 5834 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 56 to 62 bytes long. There were 0 unused item pointers. Total free space (including removable row versions) is 52116 bytes. 0 pages are or will become empty, including 0 at the end of the table. 1 pages containing 5448 free bytes are potential move destinations. CPU 0.12s/0.31u sec elapsed 1.08 sec.INFO: index tb2_pkey now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.03s/0.00u sec elapsed 0.03 sec.INFO: index tb2_idx now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.01s/0.01u sec elapsed 0.03 sec.INFO: tb2: moved 0 row versions, truncated 5834 to 5834 pages DETAIL: CPU 0.00s/0.00u sec elapsed 0.02 sec. INFO: analyzing public.tb2INFO: tb2: scanned 3000 of 5834 pages, containing 360001 live rows and 0 dead rows; 3000 rows in sample, 700082 estimated total rowsTempo total de execução da consulta: 1289 ms. View this message in context: Re: Res: Índices e otimização Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- Tarcisio F. Sassara ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Res: Re s: Índices e otimiza ção
Ok; faça agora na tb1, execute a query e nos mostre a query e o plano de execução, ok? De: moisespsena moisesps...@gmail.com Para: pgbr-geral@listas.postgresql.org.br Enviadas: Sábado, 2 de Janeiro de 2010 16:18:04 Assunto: Re: [pgbr-geral] Re s: Índices e otimização Bem, cliquei com o botão direito em cima da tabela e apareceu uma janela com as opçoes: VACUM, ANALYSE, REINDEX. Marquei a opção VACUM e logo abaixo novas opções apareceram: FULL, FREEZE e ANALYSE, marquei todas elas e mandei executar, em seguida, tive a seguinte saída na aba 'mensagens' localizada na parte inferior da janela: INFO: vacuuming public.tb2INFO: tb2: found 0 removable, 71 nonremovable row versions in 5834 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 56 to 62 bytes long. There were 0 unused item pointers. Total free space (including removable row versions) is 52116 bytes. 0 pages are or will become empty, including 0 at the end of the table. 1 pages containing 5448 free bytes are potential move destinations. CPU 0.12s/0.31u sec elapsed 1.08 sec.INFO: index tb2_pkey now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.03s/0.00u sec elapsed 0.03 sec.INFO: index tb2_idx now contains 71 row versions in 1922 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.01s/0.01u sec elapsed 0.03 sec.INFO: tb2: moved 0 row versions, truncated 5834 to 5834 pages DETAIL: CPU 0.00s/0.00u sec elapsed 0.02 sec. INFO: analyzing public.tb2INFO: tb2: scanned 3000 of 5834 pages, containing 360001 live rows and 0 dead rows; 3000 rows in sample, 700082 estimated total rowsTempo total de execução da consulta: 1289 ms. View this message in context: Re: Res: Índices e otimização Sent from the PostgreSQL - Brasil mailing list archive at Nabble.com. Veja quais são os assuntos do momento no Yahoo! +Buscados http://br.maisbuscados.yahoo.com___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/2 Tarcísio Sassara sassara.tarci...@gmail.com 2010/1/2 Leonardo Cezar lhce...@gmail.com: 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. php: doctrine, propel; python: SQLAlchemy; ruby: DataMapper; java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Abraço! Opá, Da lista conheço o SQLAlchemy, o Propel e o Doctrine. Acho que o Doctrine superou o Propel. E no site do Doctrine diz: Avoid composite keys http://www.doctrine-project.org/documentation/manual/2_0/en/best-practices#avoid-composite-keys Se da o suporte mas não recomenda o uso, não é legal. O ORM provido pelo Django também não faz direito (faz tempo que não dou uma olhada). Para novas aplicações criadas isso não é muito problemático. É só seguir as convenções, mas quando é preciso migrar deve dar uma dor de cabeça. Boa tarde, Honestamente, o uso de ORMs é um assunto deveras polêmico. Eu, pessoalmente, sou contra. Não considero boa prática ter a estrutura do banco na aplicação, não vejo razão de transportar a mesma para a aplicação, ela não precisa saber quais são as tabelas que se usa no banco. A modelagem do banco de dados pertence ao banco de dados. E também já vi muitos problemas de desempenho e más implementações quanto a muitos aspectos referentes ao banco em diversos ORMs de mercado. Incluindo Doctrine, Propel, Hibernate, entre outros. Mas isso é minha visão pessoal. Por outro lado, tenho amigos que são excelentes desenvolvedores (eu sou analista de dados, mesmo sabendo programar não tenho visão de programador) que adoram o uso de ORMs. Muitos deles gostam de doctrine para PHP e Hibernate para Java. Mesmo ao apontar os problemas que encontrei nessas ferramentas, eles consideram que esses ORMs são ótimas alternativas e ajudam muito. Mesmo discordando tenho de aceitar a opnião deles pois assim é o mundo do desenvolvimento de software: há diversas frentes, e quase nunca apenas uma está correta. Eu, pessoalmente, considero melhor prática usar visões e procedures para acessar dados do banco ou mesmo alterá-los, com poucas excessões. O programa não precisa saber o que está em cada tabela, precisa apenas solicitar que, por exemplo, insira um novo cliente e mandar os dados dele. E depois precisa ler os dados do mesmo, não se preocupando se tem 1, 2, 3, ou mais tabelas que compooem essa informação. Essa é a minha visão, é como faria. Mas se entrarmos em discussão quanto a isso a coisa vai longe, é um assunto muito polêmico. Abraços, André. PS: o hibernate não é baseado no JPA, pelo que me recordo é o contrário. -- Tarcisio F. Sassara ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- André de Camargo Fernandes ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Res: Eliminar Conexões Perdidas
Caros colegas da lista: E no caso de um servidor de aplicações (TOMCAT) onde, após algum erro no programa (que ninguém consegue rastrear), a conexão fica BUZY eternamente? Tem como matar? Existe algum arquivo de log onde eu possa verificar isso? No aguardo, Márcio de Figueiredo Moura e Castro De: JotaComm jota.c...@gmail.com Para: fabriziome...@gmail.com; Comunidade PostgreSQL Brasileira pgbr-geral@listas.postgresql.org.br Enviadas: Sábado, 2 de Janeiro de 2010 17:35:36 Assunto: Re: [pgbr-geral] Eliminar Conexões Perdidas Olá, Fabrízio 2009/12/31 Fabrízio de Royes Mello fabriziome...@gmail.com Pessoal, Estou sofrendo com um problema de algumas conexões ficarem ativas com o PostgreSQL após uma queda de energia onde todos os clientes foram desligados e o servidor, por estar ligado a um nobreak não caiu, e com isso ao ser restabelecida a energia elétrica (o servidor não foi reiniciado) as estações começam a conectar novamente, só que como já tem conexões ativas (que ficaram perdidas após a queda de energia) acaba estourando o max_connections com as novas conexões... Diante disso gostaria de trocar algumas idéias (ou se existe uma solução pronta que eu desconheça fico agradecido) pois pensei em criar algum script que verifique o client_addr e o client_port da pg_stat_activity e verificar o status do socket no sistema operacional com o netstat, e caso ele não esteja como ESTABELECIDO efetuar a eliminacao do processo... Essa é uma alternativa viável ou existe alguma forma mais elegante de contornar isso?? Esta seria uma forma de vocês fazer. O PostgreSQL tem alguns parâmetros que você pode configurar encerrar conexões IDLE, que é o caso que me parece. Os parâmetros são: tcp_keepalives_idle, tcp_keepalives_interval e tcp_keepalives_count. Sistema Operacional: Windows 2003 Versão do PostgreSQL: 8.2.14 -- Fabrízio de Royes Mello Blog sobre TI: http://fabriziomello.blogspot.com ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral []s -- JotaComm http://jotacomm.wordpress.com Veja quais são os assuntos do momento no Yahoo! +Buscados http://br.maisbuscados.yahoo.com___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/2 Leonardo Cezar lhce...@gmail.com: 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Que eu saiba, Hibernate é contraproducente para uso de chaves. -- skype:leandro.gfc.dutra?chat Yahoo!: ymsgr:sendIM?lgcdutra +55 (11) 3854 7191 gTalk: xmpp:leand...@jabber.org +55 (11) 9406 7191ICQ/AIM: aim:GoIM?screenname=61287803 BRAZIL GMT-3 MSN: msnim:chat?contact=lean...@dutra.fastmail.fm ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/2 Tarcísio Sassara sassara.tarci...@gmail.com: 2010/1/2 Leonardo Cezar lhce...@gmail.com: 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. Para novas aplicações criadas isso não é muito problemático. É só seguir as convenções Pelo contrário… criar aplicações sem poder usar chaves naturais é um terror. -- skype:leandro.gfc.dutra?chat Yahoo!: ymsgr:sendIM?lgcdutra +55 (11) 3854 7191 gTalk: xmpp:leand...@jabber.org +55 (11) 9406 7191ICQ/AIM: aim:GoIM?screenname=61287803 BRAZIL GMT-3 MSN: msnim:chat?contact=lean...@dutra.fastmail.fm Sent from Sao Paulo, SP, Brazil ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Índices e otimização
JotaComm wrote: Qual a versão do seu PostgreSQL? Postgres Studio Advanced Server 8.3R2 JotaComm wrote: Você pode colocar aqui a definição da tabela? CREATE TABLE public.tb2 ( idtb2 BIGSERIAL, idtb1 BIGINT NOT NULL, sobre VARCHAR(20), CONSTRAINT tb2_pkey PRIMARY KEY(idtb2) ); CREATE INDEX tb2_idx ON public.tb2 USING btree (idtb1); CREATE TABLE public.tb1 ( idtb1 BIGSERIAL, nome VARCHAR(20), CONSTRAINT tb1_pkey PRIMARY KEY(idtb1) ); JotaComm wrote: Veja o meu exemplo: Criação da tabela. postgres=# CREATE TABLE tab1(codigo INTEGER); CREATE TABLE Inserção de registros. postgres=# INSERT INTO tab1 VALUES (generate_series(1,60)); INSERT 0 60 postgres=# SELECT count(*) FROM tab1; count 60 (1 row) postgres=# SELECT * FROM tab1 WHERE codigo=500; codigo 500 (1 row) Time: 71,537 ms --Tempo da execução da consulta. postgres=# postgres=# EXPLAIN SELECT * FROM tab1 WHERE codigo=500; QUERY PLAN Seq Scan on tab1 (cost=0.00..10155.00 rows=1 width=4) Filter: (codigo = 500) (2 rows) Time: 0,643 ms --Tempo da execução do comando EXPLAIN. Adição de uma PK. Ao fazer isso automaticamente um índice será criado. postgres=# ALTER TABLE tab1 ADD PRIMARY KEY(codigo); NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index tab1_pkey for table tab1 ALTER TABLE postgres=# postgres=# SELECT * FROM tab1 WHERE codigo=500; codigo 500 (1 row) Time: 0,851 ms --Tempo da execução da consulta. postgres=# EXPLAIN SELECT * FROM tab1 WHERE codigo=500; QUERY PLAN -- Index Scan using tab1_pkey on tab1 (cost=0.00..8.33 rows=1 width=4) Index Cond: (codigo = 500) (2 rows) Time: 1,391 ms --Tempo da execução do comando EXPLAIN. Faça este teste e se o resultado for diferente do apresentado aqui, poste o seu resultado. Recriei as tabelas e inserir novos registros: -- registros de tb1 INSERT INTO tb1 (nome) VALUES ('nome_' || generate_series(1,60)); -- registros de tb2 com idtb1 = 2 INSERT INTO tb2 (idtb1, sobre) VALUES (2, 'sobre_' || generate_series(1,60)); -- registros de tb2 com idtb1 = 50 INSERT INTO tb2 (idtb1, sobre) VALUES (50, 'sobre_' || generate_series(1,60)); -- contar registros de tb1 SELECT count(idtb1) FROM tb1; count(idtb1) -- 60 (1 row) -- contar registros de tb2 SELECT count(idtb2) FROM tb2; count(idtb1) -- 120 (1 row) Executei o VACUM do PGAdmin nas duas tabelas: TB1: INFO: vacuuming public.tb1INFO: tb1: found 0 removable, 60 nonremovable row versions in 3822 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 39 to 44 bytes long. There were 0 unused item pointers. Total free space (including removable row versions) is 1 bytes. 0 pages are or will become empty, including 0 at the end of the table. 1 pages containing 3592 free bytes are potential move destinations. CPU 0.09s/0.18u sec elapsed 1.58 sec. INFO: index tb1_pkey now contains 60 row versions in 1648 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.00s/0.00u sec elapsed 0.00 sec. INFO: tb1: moved 0 row versions, truncated 3822 to 3822 pages DETAIL: CPU 0.00s/0.00u sec elapsed 0.00 sec. INFO: analyzing public.tb1INFO: tb1: scanned 3000 of 3822 pages, containing 470946 live rows and 0 dead rows; 3000 rows in sample, 599985 estimated total rowsTempo total de execução da consulta: 1704 ms. TB2: INFO: vacuuming public.tb2INFO: tb2: found 0 removable, 120 nonremovable row versions in 8824 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 48 to 53 bytes long. There were 0 unused item pointers. Total free space (including removable row versions) is 74576 bytes. 0 pages are or will become empty, including 0 at the end of the table. 1 pages containing 3968 free bytes are potential move destinations. CPU 0.23s/0.59u sec elapsed 3.25 sec.INFO: index tb2_pkey now contains 120 row versions in 3293 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.00s/0.00u sec elapsed 0.00 sec.INFO: index tb2_idx now contains 120 row versions in 4172 pages DETAIL: 0 index pages have been deleted, 0 are currently reusable. CPU 0.01s/0.00u sec elapsed 0.00 sec. INFO: tb2: moved 0 row versions, truncated 8824 to 8824 pages DETAIL: CPU 0.00s/0.00u sec elapsed 0.00 sec.INFO: analyzing public.tb2INFO: tb2: scanned 3000 of 8824 pages, containing 407934 live rows and 0 dead rows; 3000 rows in sample, 1199870 estimated total rowsTempo total de execução da consulta: 3425 ms. Um registro de tb1: SELECT * FROM tb1 WHERE idtb1 = 50; idtb1 | nome -- 50 | nome_50 (1 row)
[pgbr-geral] LATIN1 - Windows
Salve Galera, Gostaria da ajuda de vocês. Como faço pro PostGres aceitar a criação de base com LATIN1 no windows? Desde já agradeço []s Marcelo Souza -- Antes de imprimir pense em sua responsabilidade e compromisso com o MEIO AMBIENTE. ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Uso de Campos Padrões
2010/1/2 Andre Fernandes fernandes.an...@gmail.com: 2010/1/2 Tarcísio Sassara sassara.tarci...@gmail.com 2010/1/2 Leonardo Cezar lhce...@gmail.com: 2010/1/1 Tarcísio Sassara sassara.tarci...@gmail.com: Ainda não conheço uma biblioteca/framework ORM que faz uso adequado de chaves naturais compostas. php: doctrine, propel; python: SQLAlchemy; ruby: DataMapper; java: qualquer framework baseado na porcaria do JPA, por exemplo hibernate; Abraço! Opá, Da lista conheço o SQLAlchemy, o Propel e o Doctrine. Acho que o Doctrine superou o Propel. E no site do Doctrine diz: Avoid composite keys http://www.doctrine-project.org/documentation/manual/2_0/en/best-practices#avoid-composite-keys Se da o suporte mas não recomenda o uso, não é legal. O ORM provido pelo Django também não faz direito (faz tempo que não dou uma olhada). Para novas aplicações criadas isso não é muito problemático. É só seguir as convenções, mas quando é preciso migrar deve dar uma dor de cabeça. Boa tarde, Honestamente, o uso de ORMs é um assunto deveras polêmico. Yah! Muito! Existe situações que eles podem ser ignorados ou bem úteis. Eu, pessoalmente, sou contra. Não considero boa prática ter a estrutura do banco na aplicação, não vejo razão de transportar a mesma para a aplicação, ela não precisa saber quais são as tabelas que se usa no banco. A modelagem do banco de dados pertence ao banco de dados. Concordo especialmente com a seguinte afirmação: Não considero boa prática ter a estrutura do banco na aplicação. Existe um problema muito grande. Um pecado que os desenvolvedores estão cometendo: Estão tirando a regras do negócio do banco de dados e colocando-as na aplicação. E também já vi muitos problemas de desempenho e más implementações quanto a muitos aspectos referentes ao banco em diversos ORMs de mercado. Incluindo Doctrine, Propel, Hibernate, entre outros. Mas isso é minha visão pessoal. Alguns problemas são pelo mal uso mesmo. Por exemplo: Deixar no modo debug onde é refeito toda hora o mapeamento. Por outro lado, tenho amigos que são excelentes desenvolvedores (eu sou analista de dados, mesmo sabendo programar não tenho visão de programador) que adoram o uso de ORMs. Muitos deles gostam de doctrine para PHP e Hibernate para Java. Mesmo ao apontar os problemas que encontrei nessas ferramentas, eles consideram que esses ORMs são ótimas alternativas e ajudam muito. Mesmo discordando tenho de aceitar a opnião deles pois assim é o mundo do desenvolvimento de software: há diversas frentes, e quase nunca apenas uma está correta. Depende muito, se você iniciar um projeto do zero e seguir as recomendações das bibliotecas você consegue um ótimo desempenho. O pior caso é quando você resolve adotar a ferramenta depois de o modelo estar pronto. Assim eu concordo. Fica uma droga. Eu, pessoalmente, considero melhor prática usar visões e procedures para acessar dados do banco ou mesmo alterá-los, com poucas excessões. O programa não precisa saber o que está em cada tabela, precisa apenas solicitar que, por exemplo, insira um novo cliente e mandar os dados dele. E depois precisa ler os dados do mesmo, não se preocupando se tem 1, 2, 3, ou mais tabelas que compooem essa informação. Essa é a minha visão, é como faria. Mas se entrarmos em discussão quanto a isso a coisa vai longe, é um assunto muito polêmico. O problema é que em uma aplicação fazemos isto direto. Inserimos e pesquisamos registros em muitas sessões (telas). Se não abstrairmos, acabaremos repetindo muito código. Coisas como abrir e fechar conexão. E ainda existe o problema dos sistemas que devem ser portáveis. PS: o hibernate não é baseado no JPA, pelo que me recordo é o contrário. Ah! Isso é um assunto interessante. Realmente, na prática, o JPA veio depois do Hibernate mas conceitualmente o Hibernate é baseado no JPA. JPA é uma especificação. A JPA foi uma tentativa de especificar uma camada de persistência. (Não sei dizer se foi uma tentativa bem sucedida) Hibernate é uma implementação. O hibernate é o cara realmente. Ele é baseado na especificação JPA. Quando os caras do Java começaram a criar a JPA usaram como base o Hibernate. Foi o caso clássico da implementação que veio primeiro da especificação. -- Tarcisio F. Sassara ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Res: Res: Uso de Campos Padrões
2010/1/2 MARCIO CASTRO marciomouracas...@yahoo.com.br: Mas porquê? Desculpe-me por querer responder. Se você criar apenas uma chave primária artificial terá problemas porque ela (propositadamente) não faz nenhum sentido com o domínio da Relação e é gerada de forma a não se repetir. A chave artificial é apenas um dado e com ela você não consegue tirar nenhuma informação ou conclusão sobre a Entidade armazenada. Imagine um cenário onde gostaríamos de armazenar as informações de pessoas (nome e cpf). Podemos inserir pessoas com o mesmo nome mas não com o mesmo CPF. Criei uma tabela pessoas tendo como chave primária (artificial) um coluna que é auto incrementada (cd_pessoa) create table pessoas ( cd_pessoa serial primary key, nome character varying not null, cpf character varying not null ); Nesta tabela, podemos inserir as tuplas da seguinte maneira: insert into pessoas (nome, cpf) values ('João', '123.123.123-21'); Mas como a chave primária é a coluna cd_pessoa, poderíamos inserir novamente a mesma pessoa no banco. insert into pessoas (nome, cpf) values ('João', '123.123.123-21'); cd_pessoa | nome| cpf 1 | João | 123.123.123-21 2 | João | 123.123.123-21 Note que olhando para a chave primária não obtemos nenhuma informação. Não usamos a chave natural cpf. Não podemos usá-la para distinguir um registro. E como o Leandro escreveu: (...) criar aplicações sem poder usar chaves naturais é um terror. Mais à frente escreverei sobre como tratar este problema. -- Tradicionalmente(?) o mais adequado é encontrar qual a(s) propriedade(s) da Entidade que queremos armazenar identifica esta como sendo única. No caso CPF. create table pessoas ( cpf character varying primary key, nome character varying not null ); Assim poderemos inserir pessoas com nomes idênticos mas com cpfs distintos. Este é o comportamento desejado e aqui estamos usando adequadamente a chave natural cpf. insert into pessoas values('123.123.123-21', 'João'); insert into pessoas values('567.567.567-56', 'João'); Se nossa Relação for mais complexa, talvez uma propriedade não determine a unicidade de uma Entidade armazenada, sendo necessário usar mais de uma propriedade descrevendo assim uma chave composta. Dependendo da Relação, a chave ficaria enorme, por exemplo, vendas. Normalmente criamos uma Relação para as vendas efetuadas e outra Relação para os itens vendidos. Na relação que armazenamos as vendas teríamos que usar todas as propriedades para identificar uma única venda pois não seria possível identificá-la pelo cpf do vendedor, nem pelo cpf do vendedor mais o cpf do cliente, nem pelo cpf do vendedor mais o cpf do cliente mais a data... Por isso existe um código. Uma chave artificial que encontramos em toda Nota Fiscal. -- Eu torno as coisas mais simples. Criando as Relações usando chaves primárias artificiais e **tratando** as naturais. (ênfase na palavra tratando) A mesma Relação do primeiro exemplo. create table pessoas ( cd_pessoa serial primary key, nome character varying not null, cpf character varying NOT NULL UNIQUE ); Desta maneira, tratando a chave natural, forçando os novos registros ter um CPF único, não teremos o problema se tivéssemos apenas criado a chave primária artificial. Podemos trabalhar como se não existisse a chave artificial. Poderíamos dropar a coluna cd_pessoa que a Relação ainda manteria a consistência. Eu disse tratando as (chaves) naturais no sentido de empregá-las na lógica, de não esquecer delas, não deixá-las passarem despercebidas. Fazendo desta forma, qualquer ORM fundo de quintal conseguirá fazer os joins e de maneira geral identificar unicamente uma tupla. Para entender o motivo pelo qual estes frameworks/bibliotecas (em discussão os ORMs) que abstraem o banco de dados preferem uma única propriedade, precisamos entender mais sobre a programação orientada a objetos onde normalmente uma classe descreve as propriedades (e métodos) que um objeto terá, sendo recomendado especificar uma propriedade que identificará unicamente os objetos instanciados da mesma classe. Uma biblioteca ORM trata as tabelas de um banco de dados como sendo classes e cada registro armazenado como um objeto, portanto, é de se esperar um único atributo que descreva o registro/objeto. Assim, os desenvolvedores destas bibliotecas criaram convenções (padrões) para facilitar o trabalho de todos. Estas convenções são como acordos entre desenvolvedores e usuários finais. Cabe a nós decidir se vamos usar ou não estas bibliotecas e seguir suas convenções. Esta é uma parte de toda controvérsia. Muitos dos problemas que os desenvolvedores encontram com os ORMs é tentar migrar o que existe (código e modelo do banco), feito fora das convenções, principalmente quando o assunto é chaves compostas. Algum tempo atrás, haviam criticas aos ORMs porque eram muito burros e tinham comportamentos