NYCPHP Meetup

NYPHP.org

[nycphp-talk] Flexible Forms & How to store them...

Brian Dailey support at dailytechnology.net
Tue May 15 14:10:27 EDT 2007


This looks like what I'll ultimately be doing. I played around with some 
SQL queries and what I ended up with was similar to this - joining the 
table for each data value that I wanted to look up (and since I expect a 
matching data value, I don't even have to LEFT JOIN everything, which 
speeds it up significantly).

Thanks for all of your help and suggestions!

Mark Armendariz wrote:
>  > -----Original Message-----
>> [mailto:talk-bounces at lists.nyphp.org] On Behalf Of Brian Dailey
>> Sent: Tuesday, May 15, 2007 10:45 AM
>> Another way I've seen it handled is to have a 
>> header table and a detail table that works something like this:
>>
>> table: documents (id, date, etc)
>> table: documentdetails (documentid, fieldname, fieldvalue)
>>
>> All of the form values were stored in a fieldname=fieldvalue 
>> format inside the table. This worked nicely until you 
>> attempted to run reports on it - you couldn't easily combine 
>> data since it all existed in different table rows.
> 
> Reports aren't too difficult.  It depends on how in-depth your reports get.
> Essentially you end up joining the data table for every field.  I haven't
> done this in quite some time, but here's the idea of how you run reports
> when using field-value tables (tested in mysql 4.0.23)
> 
> CREATE TABLE data (
> 	data_id TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
> 	data_user VARCHAR(100)
> )
> 
> CREATE TABLE data_fields (
> 	field_id MEDIUMINT(6) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
> 	data_id TINYINT(3) UNSIGNED NOT NULL,
> 	field_name VARCHAR(20),
> 	field_data VARCHAR(100)
> )
> 
> 
> INSERT INTO data (data_user) VALUES ('mark at example.com');
> INSERT INTO data (data_user) VALUES ('brian at example.com');
> INSERT INTO data (data_user) VALUES ('steve at example.com');
> 
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (1, 'name',
> 'Mark');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (1, 'city',
> 'Brooklyn');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (1,
> 'state', 'NY');
> 
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (2, 'name',
> 'Brian');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (2, 'city',
> 'New York');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (2,
> 'state', 'NY');
> 
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (3, 'name',
> 'Steve');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (3, 'city',
> 'Jersey City');
> INSERT INTO data_fields (data_id, field_name, field_data) VALUES (3,
> 'state', 'NJ');
> 
> // All data with Name, City and State
> SELECT d.data_id,
>        d.data_user,
>        fName.field_data  AS Name,
>        fCity.field_data  AS City,
>        fState.field_data AS State 
> FROM   data d LEFT JOIN data_fields fName  ON d.data_id = fName.data_id  AND
> fName.field_name  = 'name'
>               LEFT JOIN data_fields fCity  ON d.data_id = fCity.data_id  AND
> fCity.field_name  = 'city'
>               LEFT JOIN data_fields fState ON d.data_id = fState.data_id AND
> fState.field_name = 'state';
> 		
> // output		
> +---------+-------------------+-------+-------------+-------+
> | data_id | data_user         | Name  | City        | State |
> +---------+-------------------+-------+-------------+-------+
> |       1 | mark at example.com  | Mark  | Brooklyn    | NY    |
> |       2 | brian at example.com | Brian | New York    | NY    |
> |       3 | steve at example.com | Steve | Jersey City | NJ    |
> +---------+-------------------+-------+-------------+-------+
> 
> // data with Name, City, State in NY
> SELECT d.data_id,
>        d.data_user,
>        fName.field_data  AS Name,
>        fCity.field_data  AS City,
>        fState.field_data AS State 
> FROM   data d LEFT JOIN data_fields fName  ON d.data_id = fName.data_id  AND
> fName.field_name  = 'name'
>               LEFT JOIN data_fields fCity  ON d.data_id = fCity.data_id  AND
> fCity.field_name  = 'city'
>               LEFT JOIN data_fields fState ON d.data_id = fState.data_id AND
> fState.field_name = 'state';
> HAVING(State = 'NY');
> 
> // output
> +---------+-------------------+-------+----------+-------+
> | data_id | data_user         | Name  | City     | State |
> +---------+-------------------+-------+----------+-------+
> |       1 | mark at example.com  | Mark  | Brooklyn | NY    |
> |       2 | brian at example.com | Brian | New York | NY    |
> +---------+-------------------+-------+----------+-------+
> 
> // data with Name, City, State in Brooklyn
> SELECT d.data_id,
>        d.data_user,
>        fName.field_data  AS Name,
>        fCity.field_data  AS City,
>        fState.field_data AS State 
> FROM   data d LEFT JOIN data_fields fName  ON d.data_id = fName.data_id  AND
> fName.field_name  = 'name'
>               LEFT JOIN data_fields fCity  ON d.data_id = fCity.data_id  AND
> fCity.field_name  = 'city'
>               LEFT JOIN data_fields fState ON d.data_id = fState.data_id AND
> fState.field_name = 'state';
> HAVING(City = 'Brooklyn');
> 
> // output
> +---------+------------------+------+----------+-------+
> | data_id | data_user        | Name | City     | State |
> +---------+------------------+------+----------+-------+
> |       1 | mark at example.com | Mark | Brooklyn | NY    |
> +---------+------------------+------+----------+-------+
> 
> // using WHERE instead of HAVING
> SELECT d.data_id,
>        d.data_user,
>        fName.field_data  AS Name,
>        fCity.field_data  AS City,
>        fState.field_data AS State 
> FROM   data d LEFT JOIN data_fields fName  ON d.data_id = fName.data_id  AND
> fName.field_name  = 'name'
>               LEFT JOIN data_fields fCity  ON d.data_id = fCity.data_id  AND
> fCity.field_name  = 'city'
>               LEFT JOIN data_fields fState ON d.data_id = fState.data_id AND
> fState.field_name = 'state';
> WHERE fCity.field_data  = 'Brooklyn'
> AND   fState.field_data = 'NY';
> 
> // output
> +---------+------------------+------+----------+-------+
> | data_id | data_user        | Name | City     | State |
> +---------+------------------+------+----------+-------+
> |       1 | mark at example.com | Mark | Brooklyn | NY    |
> +---------+------------------+------+----------+-------+
> 
> // EXPLAIN output of the last statement ('having' is a bit less efficient)
> +--------+--------+---------------+------------+---------+---------------+--
> ----+-------------+
> | table  | type   | possible_keys | key        | key_len | ref           |
> rows | Extra       |
> +--------+--------+---------------+------------+---------+---------------+--
> ----+-------------+
> | fCity  | ref    | field_name    | field_name |     120 | const,const   |
> 1 | Using where |
> | d      | eq_ref | PRIMARY       | PRIMARY    |       1 | fCity.data_id |
> 1 |             |
> | fName  | ref    | field_name    | field_name |      20 | const         |
> 2 | Using where |
> | fState | ref    | field_name    | field_name |     120 | const,const   |
> 2 | Using where |
> +--------+--------+---------------+------------+---------+---------------+--
> ----+-------------+
> 
> 
> 
> Hope that helps.
> 
> Good luck!!
> 
> Mark Armendariz
> 
> _______________________________________________
> New York PHP Community Talk Mailing List
> http://lists.nyphp.org/mailman/listinfo/talk
> 
> NYPHPCon 2006 Presentations Online
> http://www.nyphpcon.com
> 
> Show Your Participation in New York PHP
> http://www.nyphp.org/show_participation.php
> 
> 

-- 

Thanks!
- Brian Dailey
Software Developer
New York, NY
www.dailytechnology.net
-------------- next part --------------
A non-text attachment was scrubbed...
Name: support.vcf
Type: text/x-vcard
Size: 264 bytes
Desc: not available
URL: <http://lists.nyphp.org/pipermail/talk/attachments/20070515/8f85dcad/attachment.vcf>


More information about the talk mailing list