mysql - 从 MySQL 选择可用号码

标签 mysql

我即将设置一个大型服务器,将端口分配给特定对象。每个对象在创建时都会被授予一个端口,理论上这些端口可以分配多年。如果有人破坏了他们的物体,该端口就会被释放并可供争夺。如果我有一个包含所有对象及其端口的 MySQL 表,我将如何检索指定范围内的随机空闲端口?

所以: 表有idport 。查询应选择number哪里between <min> and <max> and not in table 。在 MySQL 中是否有可能出现这样的情况,或者我是否必须获取另一个表才能插入?

编辑

我目前有以下两个表:

CREATE TABLE `scjs_relays` (
    `id` INT(100) UNSIGNED NOT NULL AUTO_INCREMENT,
    `displayname` VARCHAR(50) NOT NULL COMMENT 'Name the relay shows up with at the overview',
    `origin` VARCHAR(15) NOT NULL COMMENT 'IP the packets originate from',
    `auth` BIT(1) NOT NULL DEFAULT b'',
    `authurl` VARCHAR(255) NULL DEFAULT '0' COMMENT 'URL to retrieve auth token from',
    `authtimeout` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT 'Time before person has to be reauthed',
    `steamid` BIT(1) NOT NULL DEFAULT b'',
    `teamchat` BIT(1) NOT NULL DEFAULT b'',
    `timestamp` BIT(1) NOT NULL DEFAULT b'',
    `disconnect` BIT(1) NOT NULL DEFAULT b'',
    `playerip` BIT(1) NOT NULL DEFAULT b'',
    `node` INT(10) UNSIGNED NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)
COMMENT='Chat relays'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

CREATE TABLE `scjs_ports` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `port` INT(10) UNSIGNED NOT NULL DEFAULT '0',
    `node` INT(10) UNSIGNED NOT NULL DEFAULT '0',
    `relayid` INT(100) UNSIGNED NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COMMENT='Ports per server'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

但是,如果我尝试添加外键,则会出现错误。 idscjs_users表是 AUTO_INCRMENT 因为这将是一个增量 ID,每个服务器都会有自己的 ID,并且永远不会重复使用。我目前拥有的外键如下:

ALTER TABLE `scjs_ports`
ADD CONSTRAINT `FK_relayid` FOREIGN KEY (`relayid`) REFERENCES `scjs_relays` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;

这样应该可以正常工作吗?如果我更新 scjs_relay 中的行,id永远不会改变,只有其他列,CASCADE 也是如此。这里的选项正确吗?如果一行被删除,它的端口显然被释放了,所以它应该设置为NULL。

最佳答案

对于您的应用程序,您可能需要一个表,其中包含所有可用端口以及对具有该端口的对象的引用(如果当前没有对象分配给端口,则为空)

所以可能看起来像这样:

id - autoincrement primary key
port - port number, has unique index
object_id - foreign key reference to object that has port, NULL-able, unique index if needed for reverse object to port lookups

您需要考虑允许一致的读取,因此当您要搜索打开的行并为其分配一个对象时,您需要在事务中执行此操作,并在第一次选择时锁定,这样其他连接就无法进行在尝试更新时触摸该行。

该序列可能如下所示:

START TRANSACTION;

SELECT @update_id:=id
FROM table
WHERE object_id IS NULL
ORDER BY port ASC
/*
Note you could order by RAND here if you truly want random
but query would not be optimized
*/
LIMIT 1
FOR UPDATE;

UPDATE table SET object_id = ?
WHERE id = @update_id;

COMMIT;

这里 ? 是要分配给端口的对象的对象引用。正如您所看到的,这可能很适合作为一个存储过程,您可以在其中传递对象 ID 作为参数。

关于mysql - 从 MySQL 选择可用号码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28152366/

相关文章:

mysql - 设置 MySQL 的新实例什么是当前根密码?

php - 如何将产品添加到购物车并附加数量。

mysql - 当两行的列值相等时,根据第二列选择行

java - 无法通过 SSL 连接使用 JOOQ 和 MySQL 数据库生成代码

php - 在 PHP 搜索引擎中处理简单语法

c# - C# 中加载数据 infile 查询时出错

sql - 从当前 id 获取上一行和下一行

php - 用户在线脚本PHP7兼容

mysql - innodb表中下一个id的生成

mysql - 多次使用 'as'