1

I am trying to add a foreign key to a table in Sequel Pro (using the UI).

I have two tables: "titles" and "categories" as below:

CREATE TABLE `titles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` tinytext NOT NULL,
  `category` varchar(256) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `category` (
  `key` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(256) NOT NULL DEFAULT '',
  PRIMARY KEY (`key`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

I want to create a foreign key, but nothing I try works.

The category table should be a simple lookup table. I want to assign each title a category from about 6 - 8 different choices.

Originally I had the category fields as tinytext, but I would get the error:

"MySQL Error 1170 (42000): BLOB/TEXT Column Used in Key Specification Without a Key Length".

Searched here and discovered you can't use text field that way, so I switched to Varchar and added a length of 256. Now I get:

MySQL said: Can't create table 'lit.#sql-2bf3_2' (errno: 150).

How can I create a foreign key for my table?

In Access this is pretty easily done. Somehow Access associates the unique key in the table with the lookup, but then hides the key and shows you the text field instead. How can I get a similar result with Sequel Pro and MySQL?

EDIT:

So, to clarify this is where I'm at right now. I've added an index on the category field in the titles table (first picture).

I've changed the "key" field in the category table to CategoryID (second picture).

However, I still can't seem to create the relationship between the two tables. I get the same error

So this is where I'm at right now.

enter image description here

Tim Elhajj
  • 835
  • 1
  • 9
  • 16
  • your foreign key and its reference need to be the same datatype. change `category` to an INT on titles, and index it first. – nomistic Apr 19 '15 at 04:48
  • From **Sequel Pro** you can use the _Relations_ tab (just to the right of _Content_ tab) to create foreign keys. – J.C. Gras Nov 24 '20 at 19:55

1 Answers1

2

As category will be your lookup table off of titles, you'd need to create an index on category which would refer to the foreign key. They would both need to be the same datatype (usually an INT, though sometimes you could use a CHAR(2) variable in some cases, but usually not necessary). Since you only expect 6-8 categories, I'd make it INT(1) (or may be INT(2) to be safe).

In this case, you would need to create something like categoryId which would first need to be indexed, then connect to the foreign key on categorywhich does not appear to exist; I'm not sure you want to use a term like key. Why not just make categoryId the primary key on category? this way when you create the foreign key on titles with the same name, it should link up fine.

Edit:

To clarify a little, after you've created categoryID on category you can do this under titles

ALTER TABLE Orders
ADD CONSTRAINT fk_categoryID
FOREIGN KEY (`categoryId`) REFERENCES `category`(`categoryId`)

Edit:

Here's a modification using your original layout. this should work for you:

CREATE TABLE IF NOT EXISTS `category` (
  `key` int(2) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(256) NOT NULL DEFAULT '',
  PRIMARY KEY (`key`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;



CREATE TABLE IF NOT EXISTS `titles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` tinytext NOT NULL,
  `categoryID` int(2) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `categoryID` (`categoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


ALTER TABLE `titles`
  ADD CONSTRAINT `titles_ibfk_1` FOREIGN KEY (`categoryID`) REFERENCES `category` (`key`);
nomistic
  • 2,902
  • 4
  • 20
  • 36
  • Do I need an index on the category field in the titles table? I changed the key field to categoryID (which seems like an obvious choice), but I still can't seem to connect the two tables. – Tim Elhajj Apr 19 '15 at 04:38
  • yes. To be able to use a foreign key, the referencing key must be an index. – nomistic Apr 19 '15 at 04:45
  • note, the datatypes must also be the same. You have it set as a varchar on `titles`. It should be an INT – nomistic Apr 19 '15 at 04:49
  • So the categoryID goes into the titles table? how do I get the name of the category to appear in the rows? – Tim Elhajj Apr 19 '15 at 04:49
  • On category, you have `name`. With an inner join, you can bring over the name from category for each specific categoryID on title – nomistic Apr 19 '15 at 04:51
  • you can, of course, make them both varchars, (not the way I'd do it) but you'd still need to make sure they are the same length, and you'd also need to index category on titles/ – nomistic Apr 19 '15 at 04:52
  • The main point is that for a foreign key to work, they must be the same data type and the foreign key on titles would need to be indexed. – nomistic Apr 19 '15 at 04:53
  • 1
    the issue you had before was because of different datatypes, and one was unsigned and the other was not – nomistic Apr 19 '15 at 05:11
  • 3
    Thanks so much nomistic for your diligence in this question. I was able to create it once I ticked the "unsigned" button. Wow, it's not anything like Access. :) – Tim Elhajj Apr 19 '15 at 05:28
  • I find MySQL tons better, once you get used to it, but that's just my opinion :) (I like the flexibility) – nomistic Apr 19 '15 at 05:32
  • The biggest problem with starting database learning in a Microsoft environment is that the code is overwritten. It allows you develop a lot of bad habits (for instance this "Access associates the unique key in the table with the lookup, but then hides the key and shows you the text field instead. ") It's always much better to learn how SQL works before working with a GUI, especially since MS stuff breaks so easily, and you need to mess with the underlying code. Harder to learn backward. – nomistic Apr 19 '15 at 16:23