Schema proposal based on T194697#4490343
```
lang=sql
CREATE TABLE block_target (
bt_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
bt_address tinyblob NOT NULL,
bt_user int unsigned NOT NULL default 0,
bt_auto bool NOT NULL default 0,
bt_range_start tinyblob NOT NULL,
bt_range_end tinyblob NOT NULL,
bt_count int NOT NULL default 0
);
CREATE TABLE block_entry (
be_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
be_target int NOT NULL,
be_by int unsigned NOT NULL default 0,
be_by_text varchar(255) binary NOT NULL default '',
be_by_actor bigint unsigned NOT NULL DEFAULT 0,
be_reason varbinary(767) NOT NULL default '',
be_reason_id bigint unsigned NOT NULL DEFAULT 0,
be_timestamp binary(14) NOT NULL default '',
be_anon_only bool NOT NULL default 0,
be_create_account bool NOT NULL default 1,
be_enable_autoblock bool NOT NULL default '1',
be_expiry varbinary(14) NOT NULL default '',
be_deleted bool NOT NULL default 0,
be_block_email bool NOT NULL default 0,
be_allow_usertalk bool NOT NULL default 0,
be_parent_block_id int default NULL,
be_sitewide bool NOT NULL default 1
);
CREATE TABLE block_entry_restrictions (
ber_be_id int NOT NULL,
ber_type tinyint(1) NOT NULL,
ber_value int NOT NULL,
PRIMARY KEY (ir_ipb_id, ir_type, ir_value)
);
```
>>! In T194697#4490343, @tstarling wrote:
> The unique index would be on block_target (bt_address, bt_user, bt_auto). When the number of blocks for a given target goes from zero to one, the block_target row would be inserted. A duplicate key error in this insertion would then provide the trigger for displaying a conflict warning to the admin. Adding extra blocks to a target would need to lock the block_target row, to prevent the row from being deleted while the new block_entry row referencing it is inserted. This could be done by having a statistics field, say block_target.bt_count. Updating it with `UPDATE block_target SET bt_count=bt_count+1 WHERE ...` would lock the row, preventing deletion. The `INSERT INTO block_entry` would then be done in the same transaction. On expiry or unblock, the DELETE could be done with `WHERE bt_count=0` for extra safety.