В общем случае структура базы такая:
CREATE TABLE `points` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`parent` int(11) DEFAULT NULL COMMENT 'Родитель',
`name` varchar(128) NOT NULL COMMENT 'Название',
PRIMARY KEY (`id`),
KEY `parent` (`parent`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO `points` (`parent` ,`name`) VALUES (NULL, 'Россия');
-- 'Россия': ID = 1
INSERT INTO `points` (`parent` ,`name`) VALUES (1, 'Хабаровский край');
-- 'Хабаровский край': ID = 1234
INSERT INTO `points` (`parent` ,`name`) VALUES (1234, 'Хабаровск');
Но для лучшего взаимодействия используйте Nested sets. Структура базы такая:
CREATE TABLE `points` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`left_key` int(11) DEFAULT '0' COMMENT 'Левый ключ',
`right_key` int(11) DEFAULT '0' COMMENT 'Правый ключ',
`parent` int(11) DEFAULT NULL COMMENT 'Родитель',
`level` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Уровень вложенности',
`name` varchar(128) NOT NULL COMMENT 'Название',
PRIMARY KEY (`id`),
KEY `left_key` (`left_key`),
KEY `right_key` (`right_key`),
KEY `parent` (`parent`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
Nested sets обеспечивает более быструю выборку и удобство. Единственно после любого изменения в базе вам нужно будет запускать процедуру раздачи ключей. Когда писал свой велосипед наткнулся на
zabolotnev.com/mysql-nested-sets, оттуда и подчерпнул инфу.