The ProgrammersTalk Community
Forum Register Search Today's Posts Mark Forums Read
Register

Go Back   The ProgrammersTalk Community > Web Programming > PHP


Welcome to the The ProgrammersTalk Community forums.

You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today!

If you have any problems with the registration process or your account login, please contact contact us.
Reply
 
LinkBack Thread Tools    Display Modes   
  #1 (permalink)  
Old 07-19-2007, 02:45 PM
TeraTask's Avatar
TeraTask TeraTask is offline
PT Staff*
Awards Showcase
Quality Tutorial Quality Tutorial Quality Tutorial 
Total Awards: 3
Join Date: Jun 2007
Location: Reno, NV
Posts: 428
iTrader: (0)
TeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enough
TUTORIAL: Efficient Storage of Option Choices Facilitates Searching & Retrieval

AN ERROR HAS BEEN FOUND IN THE METHODOLOGY DESCRIBED HEREIN. PLEASE SEE THE LAST FEW POSTS IN THIS THREAD BEFORE PROCEEDING.

Let me begin by offering a warning. This is a technical article detailing quite a few concepts, including some which are mathematical. If that's not your thing, then this may not be the article for you. If it is, well, then have I got a treat for you! Also, you're definitely going to want to add this thread to your notify list as I'm breaking it up into multiple parts and will post one part each day.
Programming is very much about giving system users choices and then changing behavior to reflect the users' choice(s). Searching for houses meeting a certain criteria, loading programs at system startup, and finding long-lost loved ones are just some examples where programs must change behavior based upon choices available to system users. In this article I will discuss an efficient algorithm (or methodology, if you prefer) for storing user choices which facilitates any subsequent decision-making processes from the perspective of PHP 5 OOP and MySQL.
Let's begin by taking a look at an example usage. We will then work through this example, expanding the code, until we get a fully-functional example. Amazon books has quite a few subjects and the subject list doesn't change that often, so we'll use their subject list (reference: Amazon.com: Subjects: Books: Nonfiction, Professional & Technical, Literature & Fiction, Science & More ) as our working example. We'll also work under the assumption that categories have only one attribute, name.
The next step would be to model our database and create a PHP script to handle the database connection. I'm not going to discuss most of the database model, just the part which is relevant to what we need: saving and searching through subjects as quickly as possible. That means the only real question which must be answered before we create the database is, "What type of field should subject be?" Well, we really only have three options to check out given it will be a single database field: char/varchar, enum, or integer.
  • CHAR/VARCHAR Using this as a field type would mean storing the name itself as a string in the database. Searches would require letter-by-letter comparisons and be immensely slow.
  • ENUM A rather nice choice, but additions and changes to the list would require database modification. Searching would be fairly quick for single-subject matches.
  • Integer Which type of integer would be determined by the number of subjects (where 1 subject requires 1 bit). TINYINT has 4 bits; SMALLINT has 8 bits; INT has 32 bits; and BIGINT has 64 bits. As this is the solution which will be explained below, I'm not going to say more than that for now.
We have now established that we'll be using an integer type for our preferred solution, so let's start with a core from which we'll be able to develop our solution:
  • A database for books would be helpful #Create the database (remove if you use cPanel, Plesk, or some other control panel for database creation)
    CREATE DATABASE `choices_example` ;

    #Add a database user with the proper privileges. Adjust as necessary for your server.
    GRANT ALL PRIVILEGES ON choices_example.* TO choices@localhost IDENTIFIED BY 'choices';

    #Create the table
    CREATE TABLE `book` (
    `book_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `subject` BIGINT UNSIGNED NOT NULL ,
    `name` VARCHAR( 255 ) NOT NULL,
    PRIMARY KEY (`book_id`)
    );
  • MySQL connection information all configured inside of a nice php file.
    PHP Code:
    <?php
    //Use $database as an array with all database connection information as well as pointers to the connection itself.
    $database = array('host'=>'localhost','name'=>'choices_example','user'=>'choices','password'=>'choices');
    $database['sql_connection'] = @mysql_connect($database['host'], $database['user'], $database['password']);
    $database['connection'] = @mysql_select_db($database['name'], $database['sql_connection']);
    ?>
Now, we can't get ahead of ourselves by just accepting what I've created above. Let's take a closer look at the table we create and the database connection which we'll be establishing. The table has only 3 fields - this is not because I think there are only 3 fields in the Amazon database; rather it's because we only need those 3 fields for our work here. I've never seen Amazon's database Now, each of these fields has certain characteristics, so let's discuss each of them.
  1. `book_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT This is an INTEGER because there could be millions of books. It is UNSIGNED as it is the primary key which is auto-incremented, so it must always be positive. I see a lot of programmers who forget to make this UNSIGNED which is just a waste of space!
  2. `subject` BIGINT UNSIGNED NOT NULL An UNSIGNED BIGINT can be represented as a binary number with 64 digits (bits). Amazon had 35 primary subjects when I counted, so BIGINT was the smallest number meeting the minimum requirement mentioned above of 1 subject requiring 1 bit.
  3. `name` VARCHAR( 255 ) NOT NULL Pretty straight-forward: holds the name.
The only thing I really need to say about the database connection is that the @ symbol in front of the mysql_ commands suppresses any error messages which we can subsequently trap. So go ahead and create your database and save the PHP code above to a file on that server and let's get going!

__________________
Jeremy Miller
Content Farmer - Optimized Automated Blog Posting

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!

Last edited by TeraTask : 07-27-2007 at 03:01 PM.
Reply With Quote
The Following 3 Users Say Thank You to TeraTask For This Useful Post:
admin (07-20-2007), ccoonen (09-20-2007), HelloWorld (07-19-2007)
  #2 (permalink)  
Old 07-19-2007, 03:09 PM
TeraTask's Avatar
TeraTask TeraTask is offline
PT Staff*
Awards Showcase
Quality Tutorial Quality Tutorial Quality Tutorial 
Total Awards: 3
Join Date: Jun 2007
Location: Reno, NV
Posts: 428
iTrader: (0)
TeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enough
Part 2

The only thing we've been told so far is "1 subject requires 1 bit". The reason that requirement was made is because each subject will be assigned to one bit of an integer. To do that, we can adjust our PHP script (and add in some DB validation):
PHP Code:
<?php
//Use $database as an array with all database connection information as well as pointers to the connection itself.
$database = array('host'=>'localhost','name'=>'choices_example','user'=>'choices','password'=>'choices');
$database['sql_connection'] = @mysql_connect($database['host'], $database['user'], $database['password']);
$database['connection'] = @mysql_select_db($database['name'], $database['sql_connection']);
if (!
$database['connection']) {
  echo 
'<p>Unable to connect to the database.  Please check the connection settings and try again.</p>';
} else { 
//Connected to database.
  //Assign subjects to bits:
  
$my_subjects[] = array('name'    => 'subject',
                       
'options' => array(pow(2,0)  => 'Arts & Photography',        pow(2,1)  => 'Audiocassettes',            pow(2,2)  => 'Audio CDs'
                                          
pow(2,3)  => 'Audio Downloads',           pow(2,4)  => 'Bargain Books',             pow(2,5)  => 'Biographies & Memoirs'
                                          
pow(2,6)  => 'Business & Investing ',     pow(2,7)  => 'Children\'s Books',         pow(2,8)  => 'Christian Books'
                                          
pow(2,9)  => 'Comics & Graphic Novels',   pow(2,10) => 'Computers & Internet',      pow(2,11) => 'Cooking, Food & Wine'
                                          
pow(2,12) => 'e-Books',                   pow(2,13) => 'Entertainment',             pow(2,14) => 'Espaņol'
                                          
pow(2,15) => 'Gay & Lesbian',             pow(2,16) => 'Health, Mind & Body',       pow(2,17) => 'History'
                                          
pow(2,18) => 'History',                   pow(2,19) => 'Horror',                    pow(2,20) => 'Literature & Fiction'
                                          
pow(2,21) => 'Mystery & Thrillers',       pow(2,22) => 'Nonfiction',                pow(2,23) => 'Outdoors & Nature '
                                          
pow(2,24) => 'Parenting & Families',      pow(2,25) => 'Professional & Technical',  pow(2,26) => 'Reference'
                                          
pow(2,27) => 'Religion & Spirituality',   pow(2,28) => 'Romance',                   pow(2,29) => 'Science'
                                          
pow(2,30) => 'Science Fiction & Fantasy'pow(2,31) => 'Sports',                    pow(2,32) => 'Teen'
                                          
pow(2,33) => 'Travel',                    pow(2,34) => 'Women\'s Fiction'
                                         
));
}
?>
TIP: The array above uses the pow command 35 times which does require processing. To keep the code readable, you may want to use PHP: serialize - Manual and store the serialized result as follows:
PHP Code:
 <?php
//Use $database as an array with all database connection information as well as pointers to the connection itself.
$database = array('host'=>'localhost','name'=>'choices_example','user'=>'choices','password'=>'choices');
$database['sql_connection'] = @mysql_connect($database['host'], $database['user'], $database['password']);
$database['connection'] = @mysql_select_db($database['name'], $database['sql_connection']);
if (!
$database['connection']) {
  echo 
'<p>Unable to connect to the database.  Please check the connection settings and try again.</p>';
} else { 
//Connected to database.
  //Assign subjects to bits:
  /*
  $my_subjects[] = array('name'    => 'subject',
                       'options' => array(pow(2,0)  => 'Arts & Photography',        pow(2,1)  => 'Audiocassettes',            pow(2,2)  => 'Audio CDs', 
                                          pow(2,3)  => 'Audio Downloads',           pow(2,4)  => 'Bargain Books',             pow(2,5)  => 'Biographies & Memoirs', 
                                          pow(2,6)  => 'Business & Investing ',     pow(2,7)  => 'Children\'s Books',         pow(2,8)  => 'Christian Books', 
                                          pow(2,9)  => 'Comics & Graphic Novels',   pow(2,10) => 'Computers & Internet',      pow(2,11) => 'Cooking, Food & Wine', 
                                          pow(2,12) => 'e-Books',                   pow(2,13) => 'Entertainment',             pow(2,14) => 'Espaņol', 
                                          pow(2,15) => 'Gay & Lesbian',             pow(2,16) => 'Health, Mind & Body',       pow(2,17) => 'History', 
                                          pow(2,18) => 'History',                   pow(2,19) => 'Horror',                    pow(2,20) => 'Literature & Fiction', 
                                          pow(2,21) => 'Mystery & Thrillers',       pow(2,22) => 'Nonfiction',                pow(2,23) => 'Outdoors & Nature ', 
                                          pow(2,24) => 'Parenting & Families',      pow(2,25) => 'Professional & Technical',  pow(2,26) => 'Reference', 
                                          pow(2,27) => 'Religion & Spirituality',   pow(2,28) => 'Romance',                   pow(2,29) => 'Science', 
                                          pow(2,30) => 'Science Fiction & Fantasy', pow(2,31) => 'Sports',                    pow(2,32) => 'Teen', 
                                          pow(2,33) => 'Travel',                    pow(2,34) => 'Women\'s Fiction'
                                         ));
  echo serialize($my_subjects[0]);
  */
  
$my_subjects[] = unserialize('a:2:{s:4:"name";s:7:"subject";s:7:"options";a:33:{i:1;s:18:"Arts & Photography";i:2;s:14:"Audiocassettes";i:4;s:9:"Audio CDs";i:8;s:15:"Audio Downloads";i:16;s:13:"Bargain Books";i:32;s:21:"Biographies & Memoirs";i:64;s:21:"Business & Investing ";i:128;s:16:"Children\'s Books";i:256;s:15:"Christian Books";i:512;s:23:"Comics & Graphic Novels";i:1024;s:20:"Computers & Internet";i:2048;s:20:"Cooking, Food & Wine";i:4096;s:7:"e-Books";i:8192;s:13:"Entertainment";i:16384;s:7:"Espaņol";i:32768;s:13:"Gay & Lesbian";i:65536;s:19:"Health, Mind & Body";i:131072;s:7:"History";i:262144;s:7:"History";i:524288;s:6:"Horror";i:1048576;s:20:"Literature & Fiction";i:2097152;s:19:"Mystery & Thrillers";i:4194304;s:10:"Nonfiction";i:8388608;s:18:"Outdoors & Nature ";i:16777216;s:20:"Parenting & Families";i:33554432;s:24:"Professional & Technical";i:67108864;s:9:"Reference";i:134217728;s:23:"Religion & Spirituality";i:268435456;s:7:"Romance";i:536870912;s:7:"Science";i:1073741824;s:25:"Science Fiction & Fantasy";i:-2147483648;s:6:"Sports";i:0;s:15:"Women\'s Fiction";}}');  
}
?>
The commented-out code will display the a:2:{s:4:"name";s:7:"subject";s... on the screen. Copy-and-paste that into your editor and replace all apostrophes with backslash+apostrophe. Place an apostrophe at the beginning and end of and then place inside of the unserialize function. Unserialize will re-create the array and all of the math will have been run only once. Comment out the full version to re-use when/if you ever need to add another subject.

Now, that we have each subject assigned to the bits 0-34 and created a database table which can hold the sum of any combination of those subjects, we're essentially done with setting up the framework and can begin looking at how we can use this structure. Tomorrow we'll get into using this list to actually get something done! In the meantime, please feel free to post any questions on what's above.

__________________
Jeremy Miller
Content Farmer - Optimized Automated Blog Posting

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
The Following 2 Users Say Thank You to TeraTask For This Useful Post:
admin (07-20-2007), HelloWorld (07-19-2007)
  #3 (permalink)  
Old 07-20-2007, 12:52 PM
HelloWorld's Avatar
HelloWorld HelloWorld is offline
Programming Expert
Awards Showcase
Quality Tutorial 
Total Awards: 1
Join Date: Jun 2007
Location: In front of computer...
Posts: 1,111
iTrader: (0)
HelloWorld will become famous soon enoughHelloWorld will become famous soon enoughHelloWorld will become famous soon enough
Thanx TeraTask,
I think this would help a lot to answer Google second's interview question...

Google Interview Question

__________________
PHP Code:
System.out.println("Hello World!"); 

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
  #4 (permalink)  
Old 07-27-2007, 02:48 PM
TeraTask's Avatar
TeraTask TeraTask is offline
PT Staff*
Awards Showcase
Quality Tutorial Quality Tutorial Quality Tutorial 
Total Awards: 3
Join Date: Jun 2007
Location: Reno, NV
Posts: 428
iTrader: (0)
TeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enough
While writing up the next part (yes, I was planning to get around to that), I have discovered a critical error in the implementation above. Please do not use this method until I have resolved it.

For those who like helping to solve problems, here's the problem:
Code:
                    [1] => Arts & Photography
                    [2] => Audiocassettes
                    [4] => Audio CDs
                    [8] => Audio Downloads
                    [16] => Bargain Books
                    [32] => Biographies & Memoirs
                    [64] => Business & Investing 
                    [128] => Children's Books
                    [256] => Christian Books
                    [512] => Comics & Graphic Novels
                    [1024] => Computers & Internet
                    [2048] => Cooking, Food & Wine
                    [4096] => e-Books
                    [8192] => Entertainment
                    [16384] => Espaņol
                    [32768] => Gay & Lesbian
                    [65536] => Health, Mind & Body
                    [131072] => History
                    [262144] => History
                    [524288] => Horror
                    [1048576] => Literature & Fiction
                    [2097152] => Mystery & Thrillers
                    [4194304] => Nonfiction
                    [8388608] => Outdoors & Nature 
                    [16777216] => Parenting & Families
                    [33554432] => Professional & Technical
                    [67108864] => Reference
                    [134217728] => Religion & Spirituality
                    [268435456] => Romance
                    [536870912] => Science
                    [1073741824] => Science Fiction & Fantasy
                    [-2147483648] => Sports
                    [0] => Women's Fiction
If you can look at that and see the problem, then nothing more needs to be said. If you can't see the problem, then you probably can't help (no offense).

__________________
Jeremy Miller
Content Farmer - Optimized Automated Blog Posting

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
  #5 (permalink)  
Old 07-27-2007, 02:54 PM
HelloWorld's Avatar
HelloWorld HelloWorld is offline
Programming Expert
Awards Showcase
Quality Tutorial 
Total Awards: 1
Join Date: Jun 2007
Location: In front of computer...
Posts: 1,111
iTrader: (0)
HelloWorld will become famous soon enoughHelloWorld will become famous soon enoughHelloWorld will become famous soon enough
I guess I'm one of the person who can't help that much lol.. However, here's what I found weird:

I see that they're all multiplication of 2. BUT, the last two are:

Code:
 [-2147483648] => Sports
                    [0] => Women's Fiction
Why is that?

__________________
PHP Code:
System.out.println("Hello World!"); 

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
The Following User Says Thank You to HelloWorld For This Useful Post:
TeraTask (07-27-2007)
  #6 (permalink)  
Old 07-27-2007, 02:57 PM
TeraTask's Avatar
TeraTask TeraTask is offline
PT Staff*
Awards Showcase
Quality Tutorial Quality Tutorial Quality Tutorial 
Total Awards: 3
Join Date: Jun 2007
Location: Reno, NV
Posts: 428
iTrader: (0)
TeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enough
lol. You identified the problem. That's happening b/c the number of bits necessary to store the number I've assigned to those 2 slots exceeds what PHP allows by default. I have to study their documentation to see if there's a way around that. If there is, I'll share it. If there isn't, I'll kill this thread with a big warning. I had used this method on some guy's site a couple of years back - I bet he's really screwed since he ticked me off and I stopped working with him. lol.

EDIT:
Just found
Quote:
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers. Integer size can be determined from PHP_INT_SIZE, maximum value from PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
from PHP: Integers - Manual . I guess that means I'll need to look at PHP: GMP Functions - Manual . As this stands now, I'll not be updating this thread for this methodology as implementing GMP will take some time to study it that I just do not have. Anyone who has the time is welcome to pickup this thread and continue the lesson - I have all the code which was to be used in composing this and will be happy to help as time allows.

__________________
Jeremy Miller
Content Farmer - Optimized Automated Blog Posting

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!

Last edited by Lee : 07-27-2007 at 04:06 PM. Reason: 2 posts in 3mins, just edit your last :)
Reply With Quote
  #7 (permalink)  
Old 07-27-2007, 03:01 PM
HelloWorld's Avatar
HelloWorld HelloWorld is offline
Programming Expert
Awards Showcase
Quality Tutorial 
Total Awards: 1
Join Date: Jun 2007
Location: In front of computer...
Posts: 1,111
iTrader: (0)
HelloWorld will become famous soon enoughHelloWorld will become famous soon enoughHelloWorld will become famous soon enough
Quote:
That's happening b/c the number of bits necessary to store the number I've assigned to those 2 slots exceeds what PHP allows by default.
From my experience, PHP doesn't have variable types like in any other programming languages where you have to specify whether it's an int, long, or whatever... isn't it? (which I think is less efficient because it will take the same amount of space each time variable is declared with the maximum) So is that the maximum by default for all types of variables in PHP?

__________________
PHP Code:
System.out.println("Hello World!"); 

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
  #8 (permalink)  
Old 07-27-2007, 03:05 PM
TeraTask's Avatar
TeraTask TeraTask is offline
PT Staff*
Awards Showcase
Quality Tutorial Quality Tutorial Quality Tutorial 
Total Awards: 3
Join Date: Jun 2007
Location: Reno, NV
Posts: 428
iTrader: (0)
TeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enoughTeraTask will become famous soon enough
Our posts crossed, HelloWorld. PHP does have types, you just don't have to explicitly declare them. Type-casting works, however. For example,

PHP Code:
echo (int)(6/7); 
gives 0.

__________________
Jeremy Miller
Content Farmer - Optimized Automated Blog Posting

Digg this Post! Del.Icio.Us this Post! Technorati this Post! Furl this Post! Mister Wong this Post! Newsvine this Post! Spurl this Post! Reddit this Post! Netscape this Post!
Reply With Quote
The Following User Says Thank You to TeraTask For This Useful Post:
HelloWorld (07-27-2007)
  #9 (permalink)  
Old 07-29-2007, 08:29 AM
molotov molotov is offline
Novice
Join Date: Jul 2007
Posts: 37
iTrader: (0)
molotov is on a distinguished road