国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

hyperf 二十二 數(shù)據(jù)庫 模型關(guān)系

這篇具有很好參考價值的文章主要介紹了hyperf 二十二 數(shù)據(jù)庫 模型關(guān)系。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

教程:Hyperf

一 預(yù)加載

1.1 原理

通過設(shè)置?Hyperf\Database\Model\Builder::eagerLoad加載需查詢用的model, 查詢條件子查詢使用in。

eagerLoad在Builder::eagerLoadRelations()被調(diào)用,傳入Builder::eagerLoadRelation()。eagerLoadRelation()中調(diào)用addEagerConstraints()構(gòu)造查詢。

1.2 測試

#測試
$log = User::query()->getConnection()->enableQueryLog();
$info = User::query()->with('role')->find(1);
$log = User::query()->getConnection()->getQueryLog();
var_dump($info, $log);


#測試結(jié)果
object(App1\Model\User){
……
}
array(2) {
  [0]=>
  array(3) {
    ["query"]=>
    string(94) "select * from `userinfo` where `userinfo`.`id` = ? and `userinfo`.`deleted_at` is null limit 1"
    ["bindings"]=>
    array(1) {
      [0]=>
      int(1)
    }
    ["time"]=>
    float(106.81)
  }
  [1]=>
  array(3) {
    ["query"]=>
    string(241) "select `roles`.*, `role_user`.`user_id` as `pivot_user_id`, `role_user`.`role_id` as `pivot_role_id` from `roles` inner join `role_user` on `roles`.`id` = `role_user`.`role_id` where `role_user`.`role_id` = ? and `role_user`.`user_id` in (1)"
    ["bindings"]=>
    array(1) {
      [0]=>
      int(1)
    }
    ["time"]=>
    float(20.69)
  }
}

1.3 源碼

#Hyperf\Database\Model\Model
public static function with($relations) {
        return static::query()->with(is_string($relations) ? func_get_args() : $relations);
    }
public function newCollection(array $models = []) {
        return new Collection($models);
    }


#Hyperf\Database\Model\Builder
public function with($relations) {
        $eagerLoad = $this->parseWithRelations(is_string($relations) ? func_get_args() : $relations);
        $this->eagerLoad = array_merge($this->eagerLoad, $eagerLoad);
        return $this;
    }


public function get($columns = ['*']) {
        $builder = $this->applyScopes();

        // If we actually found models we will also eager load any relationships that
        // have been specified as needing to be eager loaded, which will solve the
        // n+1 query issue for the developers to avoid running a lot of queries.
        if (count($models = $builder->getModels($columns)) > 0) {
            $models = $builder->eagerLoadRelations($models);
        }

        return $builder->getModel()->newCollection($models);
    }
public function eagerLoadRelations(array $models) {
        foreach ($this->eagerLoad as $name => $constraints) {
            // For nested eager loads we'll skip loading them here and they will be set as an
            // eager load on the query to retrieve the relation so that they will be eager
            // loaded on that query, because that is where they get hydrated as models.
            if (strpos($name, '.') === false) {
                $models = $this->eagerLoadRelation($models, $name, $constraints);
            }
        }

        return $models;
    }
protected function eagerLoadRelation(array $models, $name, Closure $constraints) {
        // First we will "back up" the existing where conditions on the query so we can
        // add our eager constraints. Then we will merge the wheres that were on the
        // query back to it in order that any where conditions might be specified.
        $relation = $this->getRelation($name);

        $relation->addEagerConstraints($models);

        $constraints($relation);

        // Once we have the results, we just match those back up to their parent models
        // using the relationship instance. Then we just return the finished arrays
        // of models which have been eagerly hydrated and are readied for return.
        return $relation->match(
            $relation->initRelation($models, $name),
            $relation->getEager(),
            $name
        );
    }
public function find($id, $columns = ['*']) {
        if (is_array($id) || $id instanceof Arrayable) {
            return $this->findMany($id, $columns);
        }

        return $this->whereKey($id)->first($columns);
    }
public function findMany($ids, $columns = ['*']) {
        if (empty($ids)) {
            return $this->model->newCollection();
        }

        return $this->whereKey($ids)->get($columns);
    }


#Hyperf\Database\Model\Relations\BelongsToMany
public function addEagerConstraints(array $models)
    {
        $whereIn = $this->whereInMethod($this->parent, $this->parentKey);

        $this->query->{$whereIn}(
            $this->getQualifiedForeignPivotKeyName(),
            $this->getKeys($models, $this->parentKey)
        );
    }


#Hyperf\Database\Model\Relations\HasOneOrMany
public function addEagerConstraints(array $models) {
        $whereIn = $this->whereInMethod($this->parent, $this->localKey);

        $this->query->{$whereIn}(
            $this->foreignKey,
            $this->getKeys($models, $this->localKey)
        );
    }

二 多態(tài)關(guān)聯(lián)

2.1 數(shù)據(jù)庫

CREATE TABLE `userinfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` tinyint(2) DEFAULT '0',
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;

CREATE TABLE `articles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `photo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `img_url` varchar(255) DEFAULT NULL,
  `ref_id` int(11) DEFAULT NULL COMMENT '關(guān)聯(lián)id',
  `ref_type` tinyint(1) DEFAULT NULL COMMENT '關(guān)聯(lián)類型 1用戶 2文章',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

?用戶和圖片一對多關(guān)系,文章和圖片一對一關(guān)系。

2.2 測試

#model
#User
public function photo() {
        return $this->morphMany(Photo::class, 'ref');
}

#Article
public function author() {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
public function photo() {
        return $this->morphOne(Photo::class, 'ref');
}

#Photo
public function ref() {
        return $this->morphTo('ref');
}




#listener
class MorphMapRelationListener implements ListenerInterface {
    public function listen(): array {
        return [
            BootApplication::class,
        ];
    }

    public function process(object $event) {
        Relation::morphMap([
            '1' => User::class,
            '2' => Article::class,
        ]);
    }
}





#config\autoload\listeners.php
return [
    "App\Listener\MorphMapRelationListener",
];

?一對多

#測試
$obj2 = User::query()->find(1);
$list = $obj2->photo->all();
foreach ($list as $key => $value) {
     var_dump($value->toArray());
}

#測試結(jié)果
array(4) {
  ["id"]=>
  int(1)
  ["img_url"]=>
  string(143) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/001O1JA0ly1hl17zd4l2qj60u01hcazo02.jpg"
  ["ref_id"]=>
  int(1)
  ["ref_type"]=>
  int(1)
}
array(4) {
  ["id"]=>
  int(3)
  ["img_url"]=>
  string(141) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/e9fbfa79gy1hku6j75abvj20j60ic76s.jpg"
  ["ref_id"]=>
  int(1)
  ["ref_type"]=>
  int(1)
}

?一對一

#測試
$log = Article::query()->getConnection()->enableQueryLog();
$obj1 = Article::query()->find(1);
$info = $obj1->photo->toArray();
var_dump($info);
$log = Article::query()->getConnection()->getQueryLog();
var_dump($log);

#測試結(jié)果
array(4) {
  ["id"]=>
  int(2)
  ["img_url"]=>
  string(143) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/001O1JA0ly1hlnbt7gu7nj60u00u0wwg02.jpg"
  ["ref_id"]=>
  int(1)
  ["ref_type"]=>
  int(2)
}
array(2) {
  [0]=>
  array(3) {
    ["query"]=>
    string(94) "select * from `articles` where `articles`.`id` = ? and `articles`.`deleted_at` is null limit 1"
    ["bindings"]=>
    array(1) {
      [0]=>
      int(1)
    }
    ["time"]=>
    float(63.42)
  }
  [1]=>
  array(3) {
    ["query"]=>
    string(116) "select * from `photo` where `photo`.`ref_id` = ? and `photo`.`ref_id` is not null and `photo`.`ref_type` = ? limit 1"
    ["bindings"]=>
    array(2) {
      [0]=>
      int(1)
      [1]=>
      int(2)
    }
    ["time"]=>
    float(1.76)
  }
}

嵌套關(guān)聯(lián)

#測試
$log = Photo::query()->getConnection()->enableQueryLog();
$photo = Photo::query()->with([
   'ref' => function (MorphTo $morphTo) {
       $morphTo->morphWith([
            Article::class => ["author"],
       ]);
    },
])->get();
$log = Photo::query()->getConnection()->getQueryLog();
var_dump($photo->toArray(), $log);


#測試結(jié)果
array(3) {
  [0]=>
  array(5) {
    ["id"]=>
    int(1)
    ["img_url"]=>
    string(143) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/001O1JA0ly1hl17zd4l2qj60u01hcazo02.jpg"
    ["ref_id"]=>
    int(1)
    ["ref_type"]=>
    int(1)
    ["ref"]=>
    array(4) {
      ["id"]=>
      int(1)
      ["name"]=>
      string(3) "123"
      ["age"]=>
      int(22)
      ["deleted_at"]=>
      NULL
    }
  }
  [1]=>
  array(5) {
    ["id"]=>
    int(2)
    ["img_url"]=>
    string(143) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/001O1JA0ly1hlnbt7gu7nj60u00u0wwg02.jpg"
    ["ref_id"]=>
    int(1)
    ["ref_type"]=>
    int(2)
    ["ref"]=>
    array(7) {
      ["id"]=>
      int(1)
      ["user_id"]=>
      int(1)
      ["title"]=>
      string(5) "test1"
      ["created_at"]=>
      string(19) "2024-01-13 10:05:51"
      ["updated_at"]=>
      string(19) "2024-01-13 10:05:53"
      ["deleted_at"]=>
      NULL
      ["author"]=>
      array(4) {
        ["id"]=>
        int(1)
        ["name"]=>
        string(3) "123"
        ["age"]=>
        int(22)
        ["deleted_at"]=>
        NULL
      }
    }
  }
  [2]=>
  array(5) {
    ["id"]=>
    int(3)
    ["img_url"]=>
    string(141) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/e9fbfa79gy1hku6j75abvj20j60ic76s.jpg"
    ["ref_id"]=>
    int(1)
    ["ref_type"]=>
    int(1)
    ["ref"]=>
    array(4) {
      ["id"]=>
      int(1)
      ["name"]=>
      string(3) "123"
      ["age"]=>
      int(22)
      ["deleted_at"]=>
      NULL
    }
  }
}
array(4) {
  [0]=>
  array(3) {
    ["query"]=>
    string(21) "select * from `photo`"
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    float(65.45)
  }
  [1]=>
  array(3) {
    ["query"]=>
    string(89) "select * from `userinfo` where `userinfo`.`id` in (1) and `userinfo`.`deleted_at` is null"
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    float(1.68)
  }
  [2]=>
  array(3) {
    ["query"]=>
    string(89) "select * from `articles` where `articles`.`id` in (1) and `articles`.`deleted_at` is null"
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    float(2.13)
  }
  [3]=>
  array(3) {
    ["query"]=>
    string(89) "select * from `userinfo` where `userinfo`.`id` in (1) and `userinfo`.`deleted_at` is null"
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    float(1.33)
  }
}
#測試
$list = Photo::query()->whereHasMorph(
            'ref',
            [
                User::class,
                Article::class,
            ],
            function (Builder $query) {
                $query->where('ref_id', 1);
            }
        )->get();
foreach ($list as $key => $value) {
      $item = $value->toArray();
      var_dump($item);
}

#測試結(jié)果
array(4) {
  ["id"]=>
  int(1)
  ["img_url"]=>
  string(143) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/001O1JA0ly1hl17zd4l2qj60u01hcazo02.jpg"
  ["ref_id"]=>
  int(1)
  ["ref_type"]=>
  int(1)
}
array(4) {
  ["id"]=>
  int(3)
  ["img_url"]=>
  string(141) "https://gitee.com/lsswear/plane_design/raw/master/%E4%B8%AD%E5%9B%BD%E5%A4%8D%E5%8F%A4%E5%9B%BE%E6%A1%88/e9fbfa79gy1hku6j75abvj20j60ic76s.jpg"
  ["ref_id"]=>
  int(1)
  ["ref_type"]=>
  int(1)
}

根據(jù)測試內(nèi)容和源碼,model設(shè)置morphMany()、morphOne()都使用Hyperf\Database\Model\Relations\HasOneOrMany::matchOneOrMany()方法。兩者參數(shù),第一個參數(shù)為有對應(yīng)關(guān)系的model,第二個參數(shù)有對應(yīng)id和對應(yīng)鍵的前綴,但是如果對應(yīng)id或?qū)?yīng)鍵不為“前綴_id”、“前綴_type”格式,可以將id設(shè)置為第三個參數(shù),type設(shè)置為第四個參數(shù)嗎,第五個參數(shù)為被調(diào)用model的對應(yīng)鍵。

例如:

#mysql
photo 
    refid
    reftype
user
    id1
article
    id2

#model
#User
public function photo() {
    return $this->morphMany(Photo::class,null,'refid','reftype','id1');
}
#Article
public function photo() {
    return $this->morphMany(Photo::class,null,'refid','reftype','id2');
}
#photo
public function ref() {
        return $this->morphTo(null,'refid','reftype');
}

一對多時返回集合對象,需要用all()等方法再獲取數(shù)據(jù),之后可以用list。一對一直接返回model對象,再調(diào)用all()等,是針對這個返回model的操作。

比如,根據(jù)上面的例子,$obj1 = Article::query()->find(1)->photo->all(),返回photo表的全部數(shù)據(jù)。

作為區(qū)分多態(tài)的字段type,字段名可自定義,字段值系統(tǒng)默認為類名,不方便使用,可以設(shè)置監(jiān)聽做對應(yīng)關(guān)系。Relation::morphMap()參數(shù)中鍵名為對應(yīng)關(guān)系的值,鍵值為類名。listen()方法設(shè)置執(zhí)行process()的類。

2.3 原理

參考:

hyperf 二十一 數(shù)據(jù)庫 模型關(guān)系-CSDN博客

hyperf console 執(zhí)行-CSDN博客

和模型關(guān)系實現(xiàn)的原理差不多都是使用__get()查詢,通過match()執(zhí)行查詢。

有點區(qū)別是中間件的設(shè)置,中間件通過ProviderConfig::load();加載配置。ListenerProviderFactory::register()執(zhí)行監(jiān)聽。

根據(jù)上述例子中監(jiān)聽設(shè)置為Relation::morphMap(),返回靜態(tài)static::$morphMap()。Relation::morphMap()傳入數(shù)組為設(shè)置,無參數(shù)為獲取。其中使用array_search()通過傳入的類名,獲取對應(yīng)的鍵名并返回。addConstraints()方法調(diào)用返回的鍵名構(gòu)造sql。

whereHasMorph()使用Hyperf\Database\Model\Concerns\HasRelationships::belongsTo()實現(xiàn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-804248.html

2.4 源碼

2.4.1 監(jiān)聽執(zhí)行

#Hyperf\Framework\ApplicationFactory
class ApplicationFactory
{
    public function __invoke(ContainerInterface $container)
    {
        if ($container->has(EventDispatcherInterface::class)) {
            $eventDispatcher = $container->get(EventDispatcherInterface::class);
            $eventDispatcher->dispatch(new BootApplication());
        }
        ……
        $application = new Application();

        if (isset($eventDispatcher) && class_exists(SymfonyEventDispatcher::class)) {
            $application->setDispatcher(new SymfonyEventDispatcher($eventDispatcher));
        }

        foreach ($commands as $command) {
            $application->add($container->get($command));
        }
        return $application;
    }
}

#Hyperf\Event\EventDispatcherFactory
class EventDispatcherFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $listeners = $container->get(ListenerProviderInterface::class);
        $stdoutLogger = $container->get(StdoutLoggerInterface::class);
        return new EventDispatcher($listeners, $stdoutLogger);
    }
}

#Hyperf\Event\ConfigProvider
class ConfigProvider
{
    public function __invoke(): array
    {
        return [
            'dependencies' => [
                ListenerProviderInterface::class => ListenerProviderFactory::class,
                EventDispatcherInterface::class => EventDispatcherFactory::class,
            ],
            'annotations' => [
                'scan' => [
                    'paths' => [
                        __DIR__,
                    ],
                ],
            ],
        ];
    }
}

#Hyperf\Event\ListenerProviderFactory
public function __invoke(ContainerInterface $container)
    {
        $listenerProvider = new ListenerProvider();

        // Register config listeners.
        $this->registerConfig($listenerProvider, $container);

        // Register annotation listeners.
        $this->registerAnnotations($listenerProvider, $container);

        return $listenerProvider;
    }
private function registerAnnotations(ListenerProvider $provider, ContainerInterface $container): void
    {
        foreach (AnnotationCollector::list() as $className => $values) {
            /** @var Listener $annotation */
            if ($annotation = $values['_c'][Listener::class] ?? null) {
                $this->register($provider, $container, $className, (int) $annotation->priority);
            }
        }
    }
private function register(ListenerProvider $provider, ContainerInterface $container, string $listener, int $priority = 1): void
    {
        $instance = $container->get($listener);
        if ($instance instanceof ListenerInterface) {
            foreach ($instance->listen() as $event) {
                $provider->on($event, [$instance, 'process'], $priority);
            }
        }
    }

2.4.2 自定義多態(tài)映射

#Hyperf\Database\Model\Relations\Relation
public static function morphMap(array $map = null, $merge = true) {
        $map = static::buildMorphMapFromModels($map);

        if (is_array($map)) {
            static::$morphMap = $merge && static::$morphMap
            ? $map+static::$morphMap : $map;
        }

        return static::$morphMap;
    }
#Hyperf\Database\Model\Concerns\HasRelationships
public function getMorphClass() {
        $morphMap = Relation::morphMap();

        if (!empty($morphMap) && in_array(static::class, $morphMap)) {
            return array_search(static::class, $morphMap, true);
        }

        return static::class;
    }

#Hyperf\Database\Model\Relations\MorphOneOrMany
public function __construct(Builder $query, Model $parent, $type, $id, $localKey)
    {
        $this->morphType = $type;

        $this->morphClass = $parent->getMorphClass();

        parent::__construct($query, $parent, $id, $localKey);
    }
public function addConstraints()
    {
        if (Constraint::isConstraint()) {
            parent::addConstraints();

            $this->query->where($this->morphType, $this->morphClass);
        }
    }

2.4.3 多態(tài)關(guān)聯(lián)查詢

#Hyperf\Database\Model\Concerns\QueriesRelationships
public function whereHasMorph($relation, $types, Closure $callback = null, $operator = '>=', $count = 1)
    {
        return $this->hasMorph($relation, $types, $operator, $count, 'and', $callback);
    }
public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null)
    {
        $relation = $this->getRelationWithoutConstraints($relation);

        $types = (array) $types;

        if ($types === ['*']) {
            $types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->filter()->all();

            foreach ($types as &$type) {
                $type = Relation::getMorphedModel($type) ?? $type;
            }
        }

        return $this->where(function ($query) use ($relation, $callback, $operator, $count, $types) {
            foreach ($types as $type) {
                $query->orWhere(function ($query) use ($relation, $callback, $operator, $count, $type) {
                    $belongsTo = $this->getBelongsToRelation($relation, $type);

                    if ($callback) {
                        $callback = function ($query) use ($callback, $type) {
                            return $callback($query, $type);
                        };
                    }

                    $query->where($relation->getMorphType(), '=', (new $type())->getMorphClass())
                        ->whereHas($belongsTo, $callback, $operator, $count);
                });
            }
        }, null, null, $boolean);
    }
protected function getBelongsToRelation(MorphTo $relation, $type)
    {
        $belongsTo = Relation::noConstraints(function () use ($relation, $type) {
            return $this->model->belongsTo(
                $type,
                $relation->getForeignKeyName(),
                $relation->getOwnerKeyName()
            );
        });

        $belongsTo->getQuery()->mergeConstraintsFrom($relation->getQuery());

        return $belongsTo;
    }

到了這里,關(guān)于hyperf 二十二 數(shù)據(jù)庫 模型關(guān)系的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Django的mysql數(shù)據(jù)庫問題:同一個模型(同一張表)中的不同記錄也是可以相互關(guān)聯(lián)的【使用“自引用關(guān)系”】

    是的,確實可以在Django的模型中使用外鍵來建立同一模型中不同記錄之間的關(guān)聯(lián)關(guān)系。這樣的關(guān)聯(lián)關(guān)系被稱為自引用關(guān)系(self-referential relationship)或者自關(guān)聯(lián)關(guān)系。通過在模型中定義外鍵字段,你可以使模型的實例與同一模型中的其他實例產(chǎn)生關(guān)聯(lián)。 在Django中,這通常通過

    2024年01月18日
    瀏覽(104)
  • Elasticsearch實戰(zhàn)(二十二)---ES數(shù)據(jù)建模與Mysql對比 一對一模型

    我們?nèi)绾伟袽ysql的模型合理的在ES中去實現(xiàn)? 就需要你對要存儲的數(shù)據(jù)足夠的了解,及對應(yīng)用場景足夠的深入分析,才能建立一個合適的模型,便于你后期擴展 實體之間的關(guān)系: 一對一 模型 一對一(1:1):一個實體最多只能能另一個實體相關(guān)聯(lián),另一個實體如是。 例:一個只能

    2024年02月10日
    瀏覽(17)
  • 關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫

    關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫

    ?關(guān)系型數(shù)據(jù)庫是以 關(guān)系(表格) 為基礎(chǔ)的數(shù)據(jù)庫,它采用了 SQL(Structured Query Language)作為數(shù)據(jù)操作語言,常見的關(guān)系型數(shù)據(jù)庫包括 MySQL、Oracle、SQL Server 等。 非關(guān)系型數(shù)據(jù)庫則是基于 文檔、鍵值、列族 等方式存儲數(shù)據(jù)的數(shù)據(jù)庫,它通常沒有固定的表結(jié)構(gòu),因此也被稱為

    2024年02月09日
    瀏覽(25)
  • 關(guān)系型數(shù)據(jù)庫與非關(guān)系型數(shù)據(jù)庫類比

    關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫都有多種不同類型,每種類型都針對不同的數(shù)據(jù)存儲需求和使用場景。以下是一些常見的關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫類型: 關(guān)系型數(shù)據(jù)庫類型: MySQL: 一種開源的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),用于處理結(jié)構(gòu)化數(shù)據(jù),適用于各種規(guī)模的應(yīng)用。

    2024年02月11日
    瀏覽(26)
  • 數(shù)據(jù)庫原理與應(yīng)用(SQL)——2、關(guān)系數(shù)據(jù)庫(E-R圖、關(guān)系模式、關(guān)系運算、關(guān)系代數(shù))

    數(shù)據(jù)庫原理與應(yīng)用(SQL)——2、關(guān)系數(shù)據(jù)庫(E-R圖、關(guān)系模式、關(guān)系運算、關(guān)系代數(shù))

    ? 目錄 關(guān)系? 關(guān)系運算? ?元組、域關(guān)系演算表達式 ?題目 ?關(guān)系代數(shù)表達式——例 元組演算表達式——例? 域演算表達式——例 ????????關(guān)系數(shù)據(jù)庫是以 二維表 形式組織數(shù)據(jù),應(yīng)用數(shù)學(xué)方法處理數(shù)據(jù)庫組織的方法。目前關(guān)系數(shù)據(jù)庫系統(tǒng)在數(shù)據(jù)管理中已占據(jù)了主導(dǎo)地位

    2023年04月08日
    瀏覽(18)
  • 【MySQL數(shù)據(jù)庫 | 第十二篇】:約束

    【MySQL數(shù)據(jù)庫 | 第十二篇】:約束

    在MySQL中, 約束是一種限制數(shù)據(jù)表中列值的規(guī)定 。保證數(shù)據(jù)庫中的數(shù)據(jù)正確,有效性和完整性。MySQL中的約束有以下幾種: 1. 主鍵約束(Primary Key Constraint) :主鍵是用于唯一標識表中每行記錄的列。主鍵約束要求 每個主鍵列的值都是唯一的,且不能為NULL 。一個表只能有一

    2024年02月08日
    瀏覽(18)
  • 數(shù)據(jù)庫:關(guān)系數(shù)據(jù)庫標準語言(二)

    一章寫不完啊,這里全是概念和實戰(zhàn),所以再來一章,希望這章可以學(xué)的好一點 連接查詢 連接查詢 :同時涉及多個表的查詢。用來連接兩個表的條件稱為連接條件或連接謂詞 。 連接條件的一般格式 : [表名1]列名1 比較運算符 [表名2]列名2 或 [表名1]列名1 BETWEEN [表名2]列名

    2023年04月09日
    瀏覽(40)
  • 重學(xué)MySQL之關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫

    重學(xué)MySQL之關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫

    1.1 關(guān)系型數(shù)據(jù)庫的特性 1.1.1 事務(wù)的特性 事務(wù),是指一個操作序列,這些操作要么都執(zhí)行,或者都不執(zhí)行,而且這一序列是無法分隔的獨立操作單位。也就是符合原子性(Atomicity)、 一致性(Consistency)、 隔離性(Isolation)和持久性(Durability)的一組操作。 原子性:指一個

    2024年02月02日
    瀏覽(25)
  • 【數(shù)據(jù)庫概論】圖數(shù)據(jù)庫 Vs 關(guān)系數(shù)據(jù)庫(1)

    【數(shù)據(jù)庫概論】圖數(shù)據(jù)庫 Vs 關(guān)系數(shù)據(jù)庫(1)

    假設(shè)有一個社交網(wǎng)絡(luò)需要用數(shù)據(jù)庫存儲,其中人與人之間的關(guān)系有:朋友(friend)、父母(parent) 首先用關(guān)系數(shù)據(jù)庫來實現(xiàn)朋友關(guān)系,需要 3 張表:people、people_relation、relation 如果要查詢 Jam 的所有朋友的信息,那么就需要連接三張表: 如果表的數(shù)據(jù)量較大,那么查詢效率就

    2024年03月14日
    瀏覽(39)
  • 數(shù)據(jù)庫系統(tǒng)概論—關(guān)系理論、數(shù)據(jù)庫設(shè)計

    數(shù)據(jù)庫系統(tǒng)概論—關(guān)系理論、數(shù)據(jù)庫設(shè)計

    主要是關(guān)系中 屬性和屬性之間的依賴關(guān)系 第一范式 :表中無表(屬性不可再分) 數(shù)據(jù)依賴:是在一個關(guān)系內(nèi)部屬性間的約束,分為函數(shù)和多值依賴。 eg:學(xué)號決定姓名 2.1函數(shù)依賴 與數(shù)學(xué)中函數(shù)概念相似,一個X只能對應(yīng)一個Y。記作X-Y 非平凡函數(shù)依賴:X-Y,但Y不屬于X 平凡函數(shù)

    2024年02月08日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包