Quando o cliente nos baralha a cabeça - Ajuda em 3 situações

Repara o count ia-me retornar o nr total de imóveis desse agente é exactamente o que não quero!

Porque em preciso de mostrar o "id_calculado" em vez do id. Repara com o count, se tiver 20 imoveis com as referências seguidas tudo bem vai-me dar 20, mas se as referências forem, 2, 4, 6 (porque a 3 apaguei e o 5 passou para outro agente) com o count já me só iria retornar 3. são coisas diferentes. Eu não preciso de fazer uma contagem, mas sim saber a que numero do id está aquela altura!

Ideia que surgiu LAST_INSERT_ID() + 1, mas não sei se resolveria, porque como iria fazer assim? Preciso é de fazer os cálculos correctos nesse novo campo, confused.
 
AndreLC ainda não percebi porque não fazes o que te indiquei que te resolve todos os problemas e te deixa a base de dados optimizada sem que sequer necessites de adicionar novos campos à tabela nem mexer no código...
 
O campo data não te ajuda? como referi...quando inseres um registo colocas a data actual da inserção, quando mudas para outro agente alteras a data para a data actual da alteração...
 
@anjo2:

Como indicaste não percebi aquela tabela anúncios!

Mas era como, +/- isto?

Código:
$lastid=mysql_query("SELECT id_calculado FROM Imoveis WHERE id_agente ='".$idagente."' ORDER BY id_calculado DESC LIMIT 1");
if(mysql_num_rows($lastid))
{
$lastid = mysql_fetch_array($lastid);
$newid = $lastid['id_calculado']+1;
}
else
{
$newid = 1;
}
mysql_insert(...);

Não necessitava de mexer na BD, nem de adicionar o campo id_calculado? Como assim, então?

--

@Vandong:

A data não tem nada a haver, porque tenho que mostrar no imóvel a referência com o "id_calculado".
 
Última edição:
Já alterei. E eu tinha um imóvel com o id = 25, agora com isso colocou o imóvel 25 de novo!

E não pode ser, pois a chave é única. Se for a mostrar ou a apagar apaga-me os dois id = 25

E se apagar e adicionar de novo vai-me adicionar como 25 de novo, o que não queria!

Acho que por aí não resolve...
 
Última edição:
Não vai nada, estás a fazer algo mal, já criei uma base de dados de teste e funciona bem, o par id, id_agente é sempre único porque são chave primária, logo se o agente tinha um imovel com o id 25, será impossível esse agente ter outro imovel com esse id, mas outro agente pode ter outro imóvel com o id 25, que é o que pretendes.

Para isto funcionar tens que apagar todos os imoveis e voltar a po-los, porque senão a contagem não fica certa.
 
Só se for isso. Se for para alterar tudo, o melhor mesmo será colocar também a id_agencia ficando:

PRIMARY KEY (`id`, `id_agente`, `id_agencia`) ou é desnecessário?


Mas mesmo assim vou ter dois ids 25 (por exemplo) na base de dados. Está certo que é referente a agentes diferentes mas o id não é igual?

E eu por exemplo para apagar registos passo o id na URL via GET:

Código:
echo "<a href=\"eliminar_imovel.php?id=$id\" onClick=\"return confirm('Deseja eliminar o im&oacute;vel com a refer&ecirc;ncia n.º ". $id ."?');\">Apagar</a>";

E no elimina_imovel.php (o relevante):

Código:
$id = (int)$_GET['id'];
$sql = mysql_query("DELETE FROM imoveis WHERE id = '$id'");

Ou seja aqui ia apagar os dois, como descalço esta bota, agora?

Obrigado pela grande ajuda.
 
o último elemento é o elemento que conta para a contagem, ou metes:
PRIMARY KEY (`id_agente`, `id`)
ou
PRIMARY KEY (`id_agencia`, `id_agente`, `id`)

Neste caso podes ter 2 agentes com o mesmo id mas de agencias diferentes, exemplo:
100-1000-1
101-1000-1
102-1000-1
Não sei se é isso que eles querem, o melhor é perguntares a eles, mas dúvido, se um agente mudar de agência deve lhe ser dado um novo id.

Como eles querem que a referência seja com id_agencia, id_agente e id_imovel, quando envias os dados para apagar ($_POST é mais recomendado que $_GET) deves enviar o id do agente e do imovel (podendo também enviar o id da agencia).
 
É a primeira opção: PRIMARY KEY (`id_agente`, `id`)

Mas e com isto resolvo também a questão das remoções, por exemplo?

E como envio o id do agente e do imóvel? Assim: eliminar_imovel.php?id=$id&id_agente=$id_agente ?

E, Por exemplo, se fizer:

Código:
SELECT CONCAT(CONCAT(CONCAT(CONCAT(id_agencia, '-'), id_agente), '-'), MAX(id)) AS Referencia
FROM imoveis
GROUP BY id_agente;
Obtenho isso do máximo é certo. Mas não preciso de efectuar nenhuma contas? É que assim vou estar sempre a apresentar o mesmo id em todos os imóveis ou estou incorrecto?

Obrigado pela ajuda.
 
Como fazes no backoffice depende de como está programado, desculpa te dizer mas estás com dúvidas de principiantes...

Para que queres o máximo? Idealmente se queres o último tens que adicionar um "where available = 1"
 
Eu sei, mas só estou com dúvidas porque nunca utilizei chaves compostas e era para perceber como funciona.

E é melhor aplicar mesmo no ID, ou num campo adicional a criar?

Estou a fazer confusão, porque se calhar tenho mesmo que apagar os dados todos e voltar a colocar...

A chave composta resolveria esse problema de remoções e se o imóvel passasse para outro agente também resolveria?

Não percebi o que quiseste dizer com o "where available = 1".

Obrigado pela ajuda.
 
Novamente, disse que isso era pouco ético, que ia contra as regras das Base de Dados e que os id's são para serem únicos, mas o cliente refere que os outros sites de imobiliárias também têm isso e então o dele também tem que ter. Que trabalham muito com essa referência e muito trabalho depende dela.

O que vai contra todas as regras das base de dados é a sua arrogância de WebDesigner.

Já agora essa da ética deve ser para colocar Ted Codd às voltas no caixão...


Existem várias maneiras de lidar graciosa e elegantemente com o problema.

Uma delas é nunca mostrar os identificadores da base de dados ao utilizador, alias, o utilizador nunca devia ver id's...

Neste caso você pergunta como é que resolve este problema... coloca nessa mesma tabela outra coluna para acomodar a referencia do produto. Imagine o caso de uma loja online onde na tabela dos produtos guarda o código de barros, os produtos são identificados — perante os dispositivos de leitura automática — pelo código de barras, no entanto existem (algumas boas) razões para a chave da base de dados não ser o código de barras, —até porque o mesmo produto pode ter vários códigos de barras...

E agora pergunta como é que resolve este problema da geração das referencias... a solução é simples: Só vai conseguir gerar a referencia depois de inserir o imovel na base de dados...


depois pode utilizar umas das 3 seguintes maneiras:
-Utiliza um stored procedure para fazer novas inserções, sendo a actualização feita pelo stored procedure
-Utiliza um trigger de base de dados, para colocar a referencia
-Utiliza uma função da linguagem de programação que está a fazer os pedidos ao motor de base de dados, para gerar a referencia e actualizar o tuplo.

Deve ter é em atenção, para garantir que o gera a referencia para o tuplo correcta, aquando da actualização do tuplo para lhe inserir a referencia (é muito comum haver "bugs" porque as race conditions não foram consideradas).



Espero ter ajudado...
 
Última edição:
Pois, realmente faz sentido.

Obrigado pela explicação.

O problema é que nunca fiz SP e triggers nem estou a ver como fazer a função para gerar a referência e actualizar a linha.

Bugs? Quero que não tenha bugs!

Como devo proceder?
 
Pois, realmente faz sentido.

Obrigado pela explicação.

O problema é que nunca fiz SP e triggers nem estou a ver como fazer a função para gerar a referência e actualizar a linha.


O meu post inicial não foi suficientemente mente claro, ou utiliza um trigger (da base de dados), ou um stored procedure (que é mais ou menos a mesma coisa que uma função da base de dados), ou então faz isso na linguagem de programação de mais alto nivel (php, java, c#, phyton ...).

Para si o mais fácil — pelo nível de conhecimentos que suponho que tenha — deve ser fazer a alteração na linguagem de programação.

Bugs? Quero que não tenha bugs!

Como devo proceder?

O bug pode acontecer numa situação de race condition, ou seja quando estão a ser inseridos muitos registos ao mesmo tempo na base de dados. Por exemplo se fizer um select max (id) from tabela, nada lhe garante que o valor retornado é o id do registo que você acabou de inserir, pode por exemplo ser retornado o id do registo que um colega ao seu lado acabou de inserir na base de dados. Você tem de acautelar isto...

Se estiver a usar mySQL pode usar a função LAST_INSERT_ID() para fazer o fetch da base dados do valor auto_increment que acabou de ser inserido e como está no manual

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.


http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Isto quer dizer que tem de tem de usar a mesma ligação que utilizou para fazer o insert, para recuperar o last_insert_id(), e só depois é que pode fechar a ligação.

Se estiver a usar outro motor de base de dados tem de procurar no manual, como lidar com as race conditions... Esta sei de cor, porque no java costumo trabalhar com mySql
 
Estou a utilizar php + mysql.

1 - Com o LAST_INSERT_ID() resolve esta situação?

O exemplo que tinha para ilustrar a situação do que pretendo:

id(imovel), id_agencia, id_agente, novo_campo_para_calculo

1, 1001, 100, 1
2, 1002, 100, 1
3, 1001, 100, 2
4, 1001, 100, 3
5, 1001, 100, 4
6, 1002, 100, 2
7, 1001, 100, 5

Se apagar o registo 5, o registo 7 mantinha no campo_calculado o 5 à mesma.
Mas, se atribuir o registo 5 ao Agente 1002 no campo calculado ficaria 3 (5, 1002, 100, 3).

É esta a minha dificuldade! O LAST_INSERT_ID() penso que aqui não resolve a situação ou resolveria?!
 
Última edição:
Eu sei, mas só estou com dúvidas porque nunca utilizei chaves compostas e era para perceber como funciona.

E é melhor aplicar mesmo no ID, ou num campo adicional a criar?

Estou a fazer confusão, porque se calhar tenho mesmo que apagar os dados todos e voltar a colocar...

A chave composta resolveria esse problema de remoções e se o imóvel passasse para outro agente também resolveria?

Não percebi o que quiseste dizer com o "where available = 1".

Obrigado pela ajuda.
É mesmo para aplicar no id. Se o imóvel passar para outro agente, o que tens de fazer é "apagar" o imóvel e criar um novo para esse novo agente, nunca vais ficar com a mesma referência para o cliente, por isso não vale a pena andar a mudar as chaves.

Como tu queres manter os dados na base de dados (não apagar realmente), o ideal será adicionares um "available" que diz se o imovel está disponível ou não, para apagar metes a 0 e quando fazes procuras só procuras quando o available está a 1.

Acho que num projecto deste tipo devias deixar para um programador mais experiente, não é propriamente algo que se faça com uma perna às costas.
 
E em vez de "apagar" ao mudar de agente não há hipótese de a referência mudar? Era isso que queria e que tento explicar e com as chaves compostas não faz, correcto?

Esse campo que falaste é o meu campo "estado". Já tenho isso na BD!

Não posso deixar para outro programador, pois tenho gosto em php e estou a fazer estágio. A questão é que faço CRUD simples e quando surge outra coisa diferente é um desafio. Mas la está, ficar parado ou adiar a questão para outra pessoa não resolve a situação. E a meu ver é a ultrapassar as dificuldades que se evolui e eu tenho gosto em evoluir.

Prefiro perguntar e aprender e darem-me críticas/conselhos/sugestões para que possa evoluir.
 
A evolução faz-se aos poucos, vais deixar muitas falhas no site, principalmente de segurança, por isso acho que estás a saltar para um projecto complexo demais.

Se queres manter a referência para que os visitantes não a percam, crias um novo campo com "moved" e outro campo com "oldid" e quando crias o novo imóvel que é cópia do que tinha o antigo agente, metes o moved a 1 e o oldid fica do genero id_agencia-id_agente-id, isto de modo a garantires que esse id que o cliente vê é sempre estático.
 
As falhas vão se corrigindo ao longo do tempo e experiência. Se não fizer nada é que não possuo experiência. É um desafio e eu dou relevância em superá-los.

Mas o id não pode ser estático... Dei vários exemplos disso.

Talvez esteja a transmitir pouca experiência, mas já tenho alguma mas sim ainda sou iniciante e ainda tenho muito que aprender.

Não estou a ver como resolver a questão. Será que não há uma solução viável?
 
Back
Topo