Re: Fw: column choices for certain data

2004-10-29 Thread Harald Fuchs
In article [EMAIL PROTECTED],
Rhino [EMAIL PROTECTED] writes:

 The chief advantage of 'SET', as far as I can tell from the manual, is
 that
 it lets you control the specific values which can be in a column without
 having to write application lookups to verify that the value you are
 supplying is one that is valid for the 'SET' column. Therefore, if you had
 only 3 business types, sole proprietorship, partnership, and corporation,
 you could put those 3 values in the set and be sure that those are the
 only
 3 values that would ever be allowed in the column. That's fine as far as
 it
 goes and is a very useful thing.

It would be mildly useful if it were true.  Unfortunately, it isn't.
When you try to insert invalid values, MySQL doesn't complain.
Instead, it silently does a conversion to something equally invalid:

  CREATE TABLE t1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
val SET ('foo', 'bar', 'baz') NOT NULL,
PRIMARY KEY (id)
  );

  INSERT INTO t1 (val) VALUES ('foo');
  INSERT INTO t1 (val) VALUES ('foo,bar');
  INSERT INTO t1 (val) VALUES ('qux');
  INSERT INTO t1 (val) VALUES ('foo,qux');

  SELECT id, val FROM t1;

returns
++-+
| id | val |
++-+
|  1 | foo |
|  2 | foo,bar |
|  3 | |
|  4 | foo |
++-+


-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]



Re: Fw: column choices for certain data

2004-10-29 Thread Rhino

- Original Message - 
From: Harald Fuchs [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Friday, October 29, 2004 7:37 AM
Subject: Re: Fw: column choices for certain data


 In article [EMAIL PROTECTED],
 Rhino [EMAIL PROTECTED] writes:

  The chief advantage of 'SET', as far as I can tell from the manual, is
  that
  it lets you control the specific values which can be in a column
without
  having to write application lookups to verify that the value you are
  supplying is one that is valid for the 'SET' column. Therefore, if you
had
  only 3 business types, sole proprietorship, partnership, and
corporation,
  you could put those 3 values in the set and be sure that those are the
  only
  3 values that would ever be allowed in the column. That's fine as far
as
  it
  goes and is a very useful thing.

 It would be mildly useful if it were true.  Unfortunately, it isn't.
 When you try to insert invalid values, MySQL doesn't complain.
 Instead, it silently does a conversion to something equally invalid:

   CREATE TABLE t1 (
 id INT UNSIGNED NOT NULL AUTO_INCREMENT,
 val SET ('foo', 'bar', 'baz') NOT NULL,
 PRIMARY KEY (id)
   );

   INSERT INTO t1 (val) VALUES ('foo');
   INSERT INTO t1 (val) VALUES ('foo,bar');
   INSERT INTO t1 (val) VALUES ('qux');
   INSERT INTO t1 (val) VALUES ('foo,qux');

   SELECT id, val FROM t1;

 returns
 ++-+
 | id | val |
 ++-+
 |  1 | foo |
 |  2 | foo,bar |
 |  3 | |
 |  4 | foo |
 ++-+

Damn! I only skimmed the article and then did a simple experiment with 'SET'
and got a rather incorrect impression of what it is doing.

I just did this experiment, which was more in-depth, due to your remarks and
learned a few things about 'SET' which are described below:


select 'Drop/Create table';
drop table if exists myset;
create table if not exists myset
(id smallint not null,
 name char(10) not null,
 sex set('M','F') not null,
 primary key(id));

select 'Populate table';
insert into myset values(1, 'Smith', 'M');
insert into myset values(2, 'Jones', 'F');
insert into myset values(3, 'Green', 'M,F');
insert into myset values(4, 'Brown', null);
insert into myset values(5, 'White', 'G');
insert into myset values(6, 'Black', 'M,G');

select 'Display table contents';
select * from myset;


When I wrote this script, I assumed that I was limiting the values in the
'sex' column to 'M' and 'F' (and 'not null' ensured that one or the other of
these values would be stored so that the column wasn't left to default to
null).

When I ran this script, I got this result:


+---+
| Drop/Create table |
+---+
| Drop/Create table |
+---+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

++
| Populate table |
++
| Populate table |
++
1 row in set (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

ERROR 1048: Column 'sex' cannot be null
Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

++
| Display table contents |
++
| Display table contents |
++
1 row in set (0.00 sec)

++---+-+
| id | name  | sex |
++---+-+
|  1 | Smith | M   |
|  2 | Jones | F   |
|  3 | Green | M,F |
|  5 | White | |
|  6 | Black | M   |
++---+-+
5 rows in set (0.00 sec)



In other words, the first three rows, which stored 'M', 'F', and 'M,F'
respectively in the 'sex' column worked fine. The fourth row, which tried to
store null in the 'sex' column, failed because the column is defined 'not
null'. The fifth row, which tried to store 'G' in the 'sex' column failed
silently and a blank was stored instead of the invalid value 'G'. The sixth
row, which tried to store the a combination of a valid value, 'M' and an
invalid value 'G', failed silently and actually stored 'M' and a blank.

According to the manual if you set a SET column to an unsupported value,
the value will be ignored. In other words, MySQL doesn't even think it is
an error to try to store something that isn't in the defined values for the
set ('M','F') in this case, so that is why you don't get an error message.

Therefore, it is clear that the SET column type is NOT working in the way I
first thought: it does not give you an error if you try to store a value
that is not in its defined list of values, although it won't store invalid
values in the table. As a result, I still feel vindicated in suggesting that
the business types be stored in their own table, which could be joined back
to the original Businesses table any time that someone needs to know which
business types

Fw: column choices for certain data

2004-10-28 Thread Rhino
Oops, I meant to copy the list on this reply too.

Rhino

- Original Message - 
From: Rhino [EMAIL PROTECTED]
To: Andy B [EMAIL PROTECTED]
Sent: Thursday, October 28, 2004 4:00 PM
Subject: Re: column choices for certain data



 - Original Message - 
 From: Andy B [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Thursday, October 28, 2004 1:15 PM
 Subject: column choices for certain data


  Hi...
  I have a db that I'm writing. It's for a business directory and one of
the
  fields/columns in the table needs to have a list of business types in it
  (i.e. retail, auto, computer and so on). Since there may be more than
one
  category that a business fits under I was wondering if SET is the best
  choice for that??
 
 I wouldn't use SET if I were you.

 I have never used the 'SET' column type in MySQL and had to look it up in
 the manual to see what it did. However, I've worked with relational
 databases for 20+ years (mostly DB2) and it doesn't have a 'SET' column
type
 in its repertoire; I've gotten used to doing things without 'SET' so maybe
 I'm just being stodgy ;-)

 The chief advantage of 'SET', as far as I can tell from the manual, is
that
 it lets you control the specific values which can be in a column without
 having to write application lookups to verify that the value you are
 supplying is one that is valid for the 'SET' column. Therefore, if you had
 only 3 business types, sole proprietorship, partnership, and corporation,
 you could put those 3 values in the set and be sure that those are the
only
 3 values that would ever be allowed in the column. That's fine as far as
it
 goes and is a very useful thing.

 However, on the negative side, there is a fixed maximum of 64 values in
the
 set. While that may be sufficient for your immediate needs, I don't think
 you can be certain that it will be sufficient for your long term needs.
For
 example, if this is an eclectic business that combines a lot of lines of
 business, you may find that it sells groceries, operates a dry cleaner,
 contains a movie theatre, and umpteen other things all under the same
 business name. You may find that 64 values isn't enough once you start
 making the set include all the different functions of the business.

 The second negative is that I don't think 'SET' is a datatype found in
most
 other databases. Therefore, if you eventually port this table over to
 another database, you may have to rework the design somewhat to get the
same
 effect, which could be a pain.

 The third negative is that putting multiple values in a single column of a
 single row violates Codd's Rules, which are the foundation of all
relational
 databases. Codd is probably rolling in his grave at the mere thought of
 doing this ;-)

 Therefore, let me suggest this, which should give you the same benefits
 without the 64 value limitation while being portable to other databases:
 store the business type in a separate table, even if there is only one
 possible value for business type for most rows in your directory.

 For example, create one table to hold the basic information about your
 business:

 create table businesses
 (registration_number int not null,
  business_name char(50) not null,
  business_location char(100) not null,
  [etc.]
  primary key(registration_number));

 Sample Contents:
 registration_numberbusiness_namebusiness_location
 1   Smitty's123 Main Street
 2   Bob's 456 Park Street

 create table business_types
 (registration_number,
  business_type char(20) not null,
  primary key(registration_number,business_types)
  foreign key(business_type) references
 business_types_lookup(business_type))TYPE=InnoDB;

 Sample Contents:
 registration_numberbusiness_type
 1pool hall
 1dry cleaner
 2restaurant

 create table business_types_lookup
 (business_type char(20) not null,
  business_type_description char(200) not null,
  primary key(business_type));

 Sample Contents:
 business_typebusiness_type_description
 pool hallgambling establishment or other den of iniquity
 restaurant eating establishment that can serve alcohol

 Do you see how this works?

 Every time you add a new business to your database, you add one row to the
 Businesses table, assigning a registration number to the business and
 recording company name, location, etc. Then, for each of the possible
 business types that apply to that business, you add a row to the
 Business_Types table. For example, Smitty's is both a pool hall and a dry
 cleaner so you add one row for each business type, linking it back to the
 Businesses table via the registration number that uniquely identifies one
 business. Any given business can have as many business types as you like,
 not just a maximum of 64.

 The third table is not strictly necessary but it is