Editado em 01/05/2013 19:20h
Desenvolvendo um sistema de enquete (Novo) PHP/MySQL Parte 1 (Planejamento)
A pedido de alguns de visitantes estou reformulando o tutorial antigo de enquete.
O primeiro passo é definirmos a estrutura que iremos trabalhar. Esta estapa é um levantamento das informações que vamos precisar.
Este será um sistema para enquetes com ilimitadas opções, sendo que no tutorial anterior eu havia criado o banco de dados com varias colunas, porém não é o ideal, pois não devemos ter colunas na tabela que não serão utilizadas.
Na segunda parte, estarei fazendo um código mais simplificado pois o foco deste tutorial é trabalhar mais o conceito da enquete.
Abaixo vou colocar o código das tabelas do banco e irei explicar o que será armazenado em cada uma.
Para entender o porque usei algumas siglas nas colunas, sugiro a leitura do Artigo:
Padrões para Nomenclatura em um banco de dados
http://blog.fabianobento.com.br/2011/09/padroes-para-nomenclatura-em-um-banco-de-dados/
Diagrama
Começando pela tabela das perguntas.
Precisamos, de um código para a enquete, a data do cadastro para sabermos quando foi cadastrada. Eu coloquei a coluna DT_INICIO, DT_FIM, para configuramos no código fonte quando a enquete será iniciada e encerrada, desta forma não seria necessário acessar o painel de controle para esta tarefa.
CREATE TABLE IF NOT EXISTS `enquete_perguntas` ( `CD_ENQUETE` int(11) NOT NULL AUTO_INCREMENT COMMENT 'codigo da enquete', `DT_CADASTRO` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'data do cadastro', `NM_ENQUETE` varchar(150) NOT NULL COMMENT 'nome da enquete', `DS_PERGUNTA` varchar(150) NOT NULL COMMENT 'pergunta da enquete', `DT_INICIO` date NOT NULL COMMENT 'data inicio que será exibida', `DT_FIM` date NOT NULL COMMENT 'data final da exibição no site', `IE_SITUACAO` enum('A','I') NOT NULL COMMENT 'situação da enquete, Ativa ou Inativa', PRIMARY KEY (`CD_ENQUETE`), UNIQUE KEY `DT_INICIO` (`DT_INICIO`), UNIQUE KEY `DT_FIM` (`DT_FIM`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Entidade para armazenar as perguntas das enquetes' AUTO_INCREMENT=2 ; -- -- Extraindo dados da tabela `enquete_perguntas` -- INSERT INTO `enquete_perguntas` (`CD_ENQUETE`, `DT_CADASTRO`, `NM_ENQUETE`, `DS_PERGUNTA`, `DT_INICIO`, `DT_FIM`, `IE_SITUACAO`) VALUES (1, '2013-04-25 17:48:15', 'Operadora de Celular', 'Qual sua operadora de celular?', '2013-04-25', '2013-04-30', 'A');
Como estamos fazendo um sistema para ilimitadas opções, precisamos de uma outra tabela para armazenas estes dados.
-- -- Estrutura da tabela `enquete_opcoes` -- CREATE TABLE IF NOT EXISTS `enquete_opcoes` ( `NR_OPCAO` int(11) NOT NULL AUTO_INCREMENT COMMENT 'numero da opção', `CD_ENQUETE` int(11) NOT NULL COMMENT 'FK codigo da enquete', `DS_OPCAO` varchar(150) NOT NULL COMMENT 'descrição da opção', `QT_VOTO` int(11) NOT NULL DEFAULT '0' COMMENT 'quantidade de votos', PRIMARY KEY (`NR_OPCAO`), KEY `FK_enquete_opcoes` (`CD_ENQUETE`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Entidade para armazenar as opções das enquetes' AUTO_INCREMENT=7 ; -- -- Extraindo dados da tabela `enquete_opcoes` -- INSERT INTO `enquete_opcoes` (`NR_OPCAO`, `CD_ENQUETE`, `DS_OPCAO`, `QT_VOTO`) VALUES (1, 1, 'Claro', 0), (2, 1, 'Tim', 0), (3, 1, 'Vivo', 0), (4, 1, 'Oi', 0), (5, 1, 'Não tenho celular.', 0), (6, 1, 'Outra operadora', 0);
Tabela para armazenar os comentários das enquetes.
-- -- Estrutura da tabela `enquete_comentarios` -- CREATE TABLE IF NOT EXISTS `enquete_comentarios` ( `NR_SEQUENCIA` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Numero sequencial', `CD_ENQUETE` int(11) NOT NULL COMMENT 'FK codigo da enquete', `DT_ENVIO` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Data que o comentário foi enviado', `NR_IP` varchar(20) NOT NULL COMMENT 'numero de IP da pessoa que enviou', `NM_PESSOA` varchar(30) NOT NULL COMMENT 'nome da pessoa', `DS_EMAIL` varchar(60) NOT NULL COMMENT 'email da pessoa', `DS_COMENTARIO` tinytext NOT NULL COMMENT 'comentario sobre a enquete', `IE_SITUACAO` enum('A','P','R') NOT NULL COMMENT 'situação, Ativo, Bloqueado, Pendente de aprovação', PRIMARY KEY (`NR_SEQUENCIA`), KEY `FK_enquete_comentarios` (`CD_ENQUETE`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Entidade para armazenar os comentários' AUTO_INCREMENT=1 ;
Esta tabela é uma das mais importantes, pois estaremos armazenando os logs de tudo o que acontecer com nossa enquete como; quem votou, quando, IP, e caso algum engraçadinho tente negativar sua enquete você poderá analisar os logs para identificar se houve alguma tentativa de burlar a enquete.
-- -- Estrutura da tabela `enquete_logs` -- CREATE TABLE IF NOT EXISTS `enquete_logs` ( `NR_SEQUENCIA` int(11) NOT NULL AUTO_INCREMENT, `CD_ENQUETE` int(11) NOT NULL, `NR_OPCAO` int(11) NOT NULL, `DT_ENVIO` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `NR_IP` varchar(20) NOT NULL, PRIMARY KEY (`NR_SEQUENCIA`), KEY `NR_OPCAO` (`NR_OPCAO`), KEY `CD_ENQUETE` (`CD_ENQUETE`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Entidade para armazenar os LOGs' AUTO_INCREMENT=19 ; -- -- Extraindo dados da tabela `enquete_logs` -- INSERT INTO `enquete_logs` (`NR_SEQUENCIA`, `CD_ENQUETE`, `NR_OPCAO`, `DT_ENVIO`, `NR_IP`) VALUES (6, 1, 4, '2013-04-30 03:26:58', '127.0.0.1'), (7, 1, 1, '2013-04-30 03:27:01', '127.0.0.1');
Relacionamentos entre as tabelas
-- -- Restrições para a tabela `enquete_comentarios` -- ALTER TABLE `enquete_comentarios` ADD CONSTRAINT `FK_enquete_comentarios` FOREIGN KEY (`CD_ENQUETE`) REFERENCES `enquete_perguntas` (`CD_ENQUETE`); -- -- Restrições para a tabela `enquete_logs` -- ALTER TABLE `enquete_logs` ADD CONSTRAINT `FK_enquete_logs` FOREIGN KEY (`NR_OPCAO`) REFERENCES `enquete_opcoes` (`NR_OPCAO`); -- -- Restrições para a tabela `enquete_opcoes` -- ALTER TABLE `enquete_opcoes` ADD CONSTRAINT `FK_enquete_opcoes` FOREIGN KEY (`CD_ENQUETE`) REFERENCES `enquete_perguntas` (`CD_ENQUETE`);
A minha enquete não tem BD. Como fazer para restringir o voto de uma pessoa
Olá, o ideal é você armazenar no banco de dados os logs de votação, mas você pode trabalhar com cokies
http://php.net/manual/en/features.cookies.php