首页 技术 正文
技术 2022年11月17日
0 收藏 732 点赞 2,328 浏览 4163 个字

如图 电影movie有多个附表,如果通过movie表来找出多个与之关联的表。

PHP获取某个表与其他表的关联关系算法

本算法规则:

  1. 外键写法必须是X_id;
  2. A与B 1对多关系,中间表表名必须是A_B,且A_B,必须包含A_id,B_id外键;

算法如下:

———————更新———————————————–

 function findRelation($db=['dbname','user','pwd','host'],$current,$father='')
{
static $pdo;
if(empty($father))
{
$pdo=new PDO("mysql:host=".(isset($db[3])?$db[3]:'localhost').";dbname={$db[0]}",$db[1],(isset($db[2])?$db[2]:''));
$pdo->exec('set names utf8');
} //临时数组,保存下面运行得出的数据
$tp=[]; //当前表的所有字段信息
$self=$pdo->query('show full columns from '.$current); //当前表是否中间表
$is_middle=0; //检查当前表是否有附表id字段
while($row = $self -> fetch())
{
//如果有发现以xxx_id命名的外键
if(stripos($row['Field'],'_id')!==FALSE)
{
//获取附表名
$extName=str_ireplace('_id','',$row['Field']); //如果当前的”附表“ 名是父表名,记录保存字段
if($extName==$father)
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],'parent_index']; continue;
}
else
{
//当前表包含有 当前表外键中的附表名(即main_extName 包含有 extName_id),则此表为中间表
if(strpos($current,$extName)!==FALSE)
$is_middle=1; //记录字段信息
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],'next_index']; //继续往下寻找附表关系
           $tp[$extName]=findRelation($db,$extName,$current); }
}
else//没发现外键,记录当前字段
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],$row['Key']];
}
} //记录当前表是否中间表
if($is_middle)
$tp['_type']='middle';
else
$tp['_type']='content'; //获取当前表注释
$cms=$pdo->query("show table status from {$db[0]} where name='{$current}'");
$one=$cms->fetch();
$tp['_comment']=$one['Comment']; //扫描以【当前表】_为开头的附表
$exts=$pdo->query('show tables like "'.$current.'_%"');
while($ext = $exts -> fetch())
{
//往下寻找当前表与每个附表的关系
$tp[$ext[0]]=findRelation($db,$ext[0],$current);
} return $tp;//返回已记录的关联关系和字段信息
} echo '<pre>';
print_r(['movie'=>findRelation(['movieshop','root'],'movie')]);
echo '</pre>';

上述算法得出的数据格式如下:

/*([主表]=>)[
[_field]=>[
[字段名] => [
[0] => 字段类型
[1] => 默认值
[2] => 字段注释
[3] => 字段索引
],
.....
]
, [_type]=>middle/content(多对多中间表/1对多内容表,不是中间表可忽略)
,
[_comment]=>表注释
,
[附表名]=>[
[_field]=>[
[字段名] => [
[0] => 字段类型
[1] => 默认值
[2] => 字段注释
[3] => 字段索引
],
.....
],
[_type]=>middle/content(多对多中间表/1对多内容表,不是中间表可忽略)
,
[_comment]=>表注释
,
[附表名]=>[
.............
]
,
...............
]
,
..........
]*/

——————————————————————————旧版—————————————————————————————

<?php/*
2016-11-03
GaZeon-------------寻找表关系方法---------------主表:main附表格式:main_extName 可能存在的表:extName判断主附的对应关系方法:如果main 有 extName_id 则 main与main_extName 为1对1关系如果main_extName 【有 且只有 main_id外键】或 【main_extName 有其他外键但不包含extName_id外键 】 则 main与main_extName 为1对多关系如果main_extName 有 main_id外键,且有 extName_id 外键,则 main与 extName为多对多关系 ,main_extName为中间表 与main为1对多关系1,获取【当前表】的所有字段,并循环字段查找_id结尾的外键
{
2,如果查找到【当前表】的外键,则判断【外键所在的表】是否【当前表】的【上一级表】:
[如果是,则【外键所在的表】为中间表,【当前表】与【外键所在的表】为1对多关系,跳过本次进入下次循环];
[如果不是,则【当前表】与【外键所在的表】为1对多关系,查找这个【外键所在的表】],
}
3,【当前表】外键查找完后,扫描以【当前表】_为开头的表:
[如果有,则循环轮流进入1程序];
4,没有,当前关联关系到达最终点,返回本次运行得出的关系信息。-----------------------------------------------------
如果一个表没有任何外键
如果这个表没有附表,则为最终表
如果这个表有附表,则查找其附表,继续寻找其表的关联关系*/
$pdo=new PDO('mysql:host=localhost;dbname=MovieShop','root','');
$pdo->exec('set names utf8');
$relation=[];function findRelation($current,$father='')
{
global $pdo;
global $relation; //临时数组,保存下面运行得出的数据
$tp=[]; //当前表的所有字段信息
$self=$pdo->query('show full columns from '.$current); //当前表是否中间表
$is_middle=0; //检查当前表是否有附表id字段
while($row = $self -> fetch())
{
//如果有发现以xxx_id命名的外键
if(stripos($row['Field'],'_id')!==FALSE)
{
//获取附表名
$extName=str_ireplace('_id','',$row['Field']); //如果当前的”附表“ 名是父表名,记录保存字段
if($extName==$father)
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],'parent_index']; continue;
}
else
{
//当前表包含有 当前表外键中的附表名(即main_extName 包含有 extName_id),则此表为中间表
if(strpos($current,$extName)!==FALSE)
$is_middle=1; //记录字段信息
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],'next_index']; //继续往下寻找附表关系
$tp[$extName]=findRelation($extName,$current); }
}
else//没发现外键,记录当前字段
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Key']];
}
} //记录当前表是否中间表
if($is_middle)
$tp['_type']='middle';
else
$tp['_type']='content'; //扫描以【当前表】_为开头的附表
$exts=$pdo->query('show tables like "'.$current.'_%"');
while($ext = $exts -> fetch())
{
//往下寻找当前表与每个附表的关系
$relation[$current][$ext[0]]=findRelation($ext[0],$current);
} return $tp;//返回已记录的关联关系和字段信息
}findRelation('movie');echo '<pre>';
print_r($relation);
echo '</pre>';

有bug请联系本人,转载需注明出处。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,497
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,910
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,744
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,498
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,136
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,300