hyperf 二十二 数据库 模型关系

这篇具有很好参考价值的文章主要介绍了hyperf 二十二 数据库 模型关系。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

教程:Hyperf

一 预加载

1.1 原理

通过设置 Hyperf\Database\Model\Builder::eagerLoad加载需查询用的model, 查询条件子查询使用in。

eagerLoad在Builder::eagerLoadRelations()被调用,传入Builder::eagerLoadRelation()。eagerLoadRelation()中调用addEagerConstraints()构造查询。

1.2 测试

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


#测试结果
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)
        );
    }

二 多态关联

2.1 数据库

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 '关联id',
  `ref_type` tinyint(1) DEFAULT NULL COMMENT '关联类型 1用户 2文章',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

 用户和图片一对多关系,文章和图片一对一关系。

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());
}

#测试结果
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);

#测试结果
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)
  }
}

嵌套关联

#测试
$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);


#测试结果
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);
}

#测试结果
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)
}

根据测试内容和源码,model设置morphMany()、morphOne()都使用Hyperf\Database\Model\Relations\HasOneOrMany::matchOneOrMany()方法。两者参数,第一个参数为有对应关系的model,第二个参数有对应id和对应键的前缀,但是如果对应id或对应键不为“前缀_id”、“前缀_type”格式,可以将id设置为第三个参数,type设置为第四个参数吗,第五个参数为被调用model的对应键。

例如:

#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()等方法再获取数据,之后可以用list。一对一直接返回model对象,再调用all()等,是针对这个返回model的操作。

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

作为区分多态的字段type,字段名可自定义,字段值系统默认为类名,不方便使用,可以设置监听做对应关系。Relation::morphMap()参数中键名为对应关系的值,键值为类名。listen()方法设置执行process()的类。

2.3 原理

参考:

hyperf 二十一 数据库 模型关系-CSDN博客

hyperf console 执行-CSDN博客

和模型关系实现的原理差不多都是使用__get()查询,通过match()执行查询。

有点区别是中间件的设置,中间件通过ProviderConfig::load();加载配置。ListenerProviderFactory::register()执行监听。

根据上述例子中监听设置为Relation::morphMap(),返回静态static::$morphMap()。Relation::morphMap()传入数组为设置,无参数为获取。其中使用array_search()通过传入的类名,获取对应的键名并返回。addConstraints()方法调用返回的键名构造sql。

whereHasMorph()使用Hyperf\Database\Model\Concerns\HasRelationships::belongsTo()实现。文章来源地址https://www.toymoban.com/news/detail-804248.html

2.4 源码

2.4.1 监听执行

#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 自定义多态映射

#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 多态关联查询

#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;
    }

到了这里,关于hyperf 二十二 数据库 模型关系的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django的mysql数据库问题:同一个模型(同一张表)中的不同记录也是可以相互关联的【使用“自引用关系”】

    是的,确实可以在Django的模型中使用外键来建立同一模型中不同记录之间的关联关系。这样的关联关系被称为自引用关系(self-referential relationship)或者自关联关系。通过在模型中定义外键字段,你可以使模型的实例与同一模型中的其他实例产生关联。 在Django中,这通常通过

    2024年01月18日
    浏览(65)
  • Elasticsearch实战(二十二)---ES数据建模与Mysql对比 一对一模型

    我们如何把Mysql的模型合理的在ES中去实现? 就需要你对要存储的数据足够的了解,及对应用场景足够的深入分析,才能建立一个合适的模型,便于你后期扩展 实体之间的关系: 一对一 模型 一对一(1:1):一个实体最多只能能另一个实体相关联,另一个实体如是。 例:一个只能

    2024年02月10日
    浏览(57)
  • 关系型数据库和非关系型数据库

     关系型数据库是以 关系(表格) 为基础的数据库,它采用了 SQL(Structured Query Language)作为数据操作语言,常见的关系型数据库包括 MySQL、Oracle、SQL Server 等。 非关系型数据库则是基于 文档、键值、列族 等方式存储数据的数据库,它通常没有固定的表结构,因此也被称为

    2024年02月09日
    浏览(45)
  • 关系型数据库与非关系型数据库类比

    关系型数据库和非关系型数据库都有多种不同类型,每种类型都针对不同的数据存储需求和使用场景。以下是一些常见的关系型数据库和非关系型数据库类型: 关系型数据库类型: MySQL: 一种开源的关系型数据库管理系统,用于处理结构化数据,适用于各种规模的应用。

    2024年02月11日
    浏览(40)
  • 数据库原理与应用(SQL)——2、关系数据库(E-R图、关系模式、关系运算、关系代数)

      目录 关系  关系运算   元组、域关系演算表达式  题目  关系代数表达式——例 元组演算表达式——例  域演算表达式——例         关系数据库是以 二维表 形式组织数据,应用数学方法处理数据库组织的方法。目前关系数据库系统在数据管理中已占据了主导地位

    2023年04月08日
    浏览(46)
  • 【MySQL数据库 | 第十二篇】:约束

    在MySQL中, 约束是一种限制数据表中列值的规定 。保证数据库中的数据正确,有效性和完整性。MySQL中的约束有以下几种: 1. 主键约束(Primary Key Constraint) :主键是用于唯一标识表中每行记录的列。主键约束要求 每个主键列的值都是唯一的,且不能为NULL 。一个表只能有一

    2024年02月08日
    浏览(50)
  • 数据库:关系数据库标准语言(二)

    一章写不完啊,这里全是概念和实战,所以再来一章,希望这章可以学的好一点 连接查询 连接查询 :同时涉及多个表的查询。用来连接两个表的条件称为连接条件或连接谓词 。 连接条件的一般格式 : [表名1]列名1 比较运算符 [表名2]列名2 或 [表名1]列名1 BETWEEN [表名2]列名

    2023年04月09日
    浏览(56)
  • 重学MySQL之关系型数据库和非关系型数据库

    1.1 关系型数据库的特性 1.1.1 事务的特性 事务,是指一个操作序列,这些操作要么都执行,或者都不执行,而且这一序列是无法分隔的独立操作单位。也就是符合原子性(Atomicity)、 一致性(Consistency)、 隔离性(Isolation)和持久性(Durability)的一组操作。 原子性:指一个

    2024年02月02日
    浏览(73)
  • 【数据库概论】图数据库 Vs 关系数据库(1)

    假设有一个社交网络需要用数据库存储,其中人与人之间的关系有:朋友(friend)、父母(parent) 首先用关系数据库来实现朋友关系,需要 3 张表:people、people_relation、relation 如果要查询 Jam 的所有朋友的信息,那么就需要连接三张表: 如果表的数据量较大,那么查询效率就

    2024年03月14日
    浏览(48)
  • 数据库介绍-非关系型数据库

    NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。 NoSQL 不依赖业务逻辑方式存储,数据存储的类型不需要一个固定形式。因此大大的增加了数据库的扩展能力。 不遵循 SQL 标准 不支持 ACID 远超于 SQL 的性能 易扩展 大读写量,高性能 数据模型灵活 高可用

    2024年02月16日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包