Here is the database layout It is fairly simple, with 3 tables Table domains: create table domains ( domain_id int auto_increment, domain varchar(100) NOT NULL, owner_id int, key( domain_id, domain)) domain_id: is an auto incremented integer used to identify the domain. It is used as a key to the "records" table. domain: is the domain name owner_id: it is a key to the owner table. Table records: create table records ( domain_id int NOT NULL, host varchar(100) not null, type char(1), val varchar(100) ) domain_id: key from the domains table host: fully qualified hostname type: dns record type, N = name server M = mail exchange server H = IN PTR for bind or Host for djbdns A = A record C = CNAME val: the value associated with the type N = no value M = distance H = IP number A = IP number C = host name An index on records is created after the table loads. This significantly increases dnsloadzone times Index record_idx create index records_idx on records ( domain_id, host ) Table owners: create table owners ( owner_id int auto_increment, username char(30) NOT NULL, password char(30), key (owner_id, username ) ) onwer_id: id of the owner, used in the domains table too username: username for login password: password for login Sample information "normal" zone: mysql> select * from domains where domain_id = 53000; +-----------+-----------+-------------+ | domain_id | owner_id | domain | +-----------+-----------+-------------+ | 53000 | 52999 | beo-tech.it | +-----------+-----------+-------------+ 1 row in set (0.00 sec) mysql> select * from records where domain_id = 53000; +-----------+-----------------------+------+------------------+ | domain_id | host | type | val | +-----------+-----------------------+------+------------------+ | 53000 | beo-tech.it | A | 62.149.128.18 | | 53000 | dns.technorail.com | N | | | 53000 | dns2.technorail.com | N | | | 53000 | ftp | C | www.beo-tech.it | | 53000 | localhost.beo-tech.it | A | 127.0.0.1 | | 53000 | mail.beo-tech.it | A | 62.149.128.18 | | 53000 | mx.beo-tech.it | M | 10 | | 53000 | mx.beo-tech.it | A | 62.149.128.17 | | 53000 | pop3 | C | mail.beo-tech.it | | 53000 | smtp.beo-tech.it | A | 62.149.128.21 | | 53000 | www.beo-tech.it | A | 62.149.130.44 | +-----------+-----------------------+------+------------------+ 11 rows in set (0.07 sec) Sample reverse: mysql> select * from domains where domain_id = 1; +-----------+-----------+-------------------------+ | domain_id | owner_id | domain | +-----------+-----------+-------------------------+ | 2 | 0 | 128.149.62.in-addr.arpa | +-----------+-----------+-------------------------+ 1 row in set (0.00 sec) mysql> select * from records where domain_id = 2; +-----------+-------------------------------+------+---------------+ | domain_id | host | type | val | +-----------+-------------------------------+------+---------------+ | 2 | dns.technorail.com | N | | | 2 | dns.technorail.com | H | 62.149.128.2 | | 2 | dns2.technorail.com | N | | | 2 | gw-adsl-atm.aruba.it | H | 62.149.128.20 | | 2 | gw-dialup-atm.aruba.it | H | 62.149.128.25 | | 2 | gw-interbusiness-atm.aruba.it | H | 62.149.128.1 | | 2 | mail.technorail.com | M | 10 | | 2 | maildomini.aruba.it | H | 62.149.128.16 | | 2 | mailmaxsql.aruba.it | H | 62.149.128.10 | | 2 | mxdomini.aruba.it | H | 62.149.128.17 | | 2 | ourwebs.aruba.it | H | 62.149.128.9 | | 2 | pop3domini.aruba.it | H | 62.149.128.18 | | 2 | radius.technorail.com | H | 62.149.128.23 | | 2 | radiusadsl.aruba.it | H | 62.149.128.13 | | 2 | radtac.technorail.com | H | 62.149.128.12 | | 2 | scambiobanner.aruba.it | H | 62.149.128.40 | | 2 | smtp.technorail.com | H | 62.149.128.19 | | 2 | smtpdomini.aruba.it | H | 62.149.128.21 | | 2 | sql.aruba.it | H | 62.149.128.11 | | 2 | sqldomini.aruba.it | H | 62.149.128.14 | | 2 | web.aruba.it | H | 62.149.128.15 | +-----------+-------------------------------+------+---------------+ 21 rows in set (0.00 sec)