Maison  >  Questions et réponses  >  le corps du texte

mysql - 寻求统计新增合同数的方案

场景

登陆用户可以随时查看某个时间段的新增合同数

部门成员关系

华东区总经理 
 |--- 华东1区经理 
 |      |---销售主管11 
 |      |    |---销售员111
 |      |    |---销售员112
 |      |---销售主管12
 |           |---销售员121
 |           |---销售员122
 |
 |
 |--- 华东2区经理 
        |---销售主管21 
        |    |---销售员211
        |    |---销售员212
        |---销售主管22
        |    |---销售员221
        |    |---销售员222
        |---销售主管23
        |    |---销售员231
        |    |---销售员232
华北区总经理 
 |--- 华北1区经理 
 |      |---销售主管31 
 |      |    |---销售员311
 |      |    |---销售员312
 |      |---销售主管32
 |           |---销售员321
 |           |---销售员322
 |
 |
 |--- 华北2区经理 
        |---销售主管41 
        |    |---销售员411
        |    |---销售员412
        |---销售主管42
        |    |---销售员421
        |    |---销售员422
        |---销售主管43
        |    |---销售员431
        |    |---销售员432
     

合同表

id          合同id
name        合同名称
created_at  创建时间
created_by  创建人
updated_at  修改时间
updated_by  修改人

计算规则

【新增合同数】 = 【所有下级的新增合同数】+【本人新增合同数】

方案1

数据库是mysql,因为上级合同数,是所有下级的合同数之和,所以,我们递归得到了用户所有下级的用户id
然后再用count(*) from 表 where (created_at时间段条件) and created_by in (所有的下级用户id,包含当前登录用户id)

问题:数据是准确的,但是效率低下,对服务器性能也有影响

方案2

单独用一个表来记录每个用户每天的新增合同数,还是先得到所有下级用户的id,然后再用
select sum(inum) from user_count where (created_at时间段条件)
and created_by in (所有的下级用户id,包含当前登录用户id)

问题:每次 增加,删除,批量删除,都要修改这个字段,如果用户量增大,计数错误的可能性非常大,虽然统计方便了,但是数据不准确

求助

我们网站要统计今日新增,昨日新增,本周新增,本月新增,本季度新增,本年新增,用户还可以自己输入时间段查询
请问大家有没有什么好的方案,可以让数据既准确,统计起来效率又高的?

巴扎黑巴扎黑2727 Il y a quelques jours716

répondre à tous(5)je répondrai

  • PHP中文网

    PHP中文网2017-05-02 09:28:05

    Pensez à mettre une copie du contrat nouvellement ajouté dans Redis et à l'effacer une fois par jour.

    répondre
    0
  • PHPz

    PHPz2017-05-02 09:28:05

    L'option 1 est l'option privilégiée. Le seul problème est qu'elle est lente à obtenir de manière récursive tout le personnel subordonné. Alors résolvons ce problème !

    Supposons que la structure approximative de la table du personnel soit la suivante, un stockage de données arborescent typique.
    ID, Nom, ParentId

    Ajoutez-y un champ Chemin, dont la valeur est le chemin d'accès à la personne, tel que -12-45-765-, où 765 est l'ID utilisateur actuel, 45 est le supérieur de 765 et 12 est le supérieur de 45.

    Avec ce champ, il est facile de filtrer tous les subordonnés d'un leader et lui-même en fonction de son identifiant. select id from employee where path like '%-45-%'

    N'oubliez pas de mettre à jour ce champ lors de la mise à jour future des affiliations du personnel.

    répondre
    0
  • 阿神

    阿神2017-05-02 09:28:05

    Si vous disposez d'une grande quantité de données, vous devez les interroger et les calculer à chaque fois que vous les consultez. C'est très, très stressant, quelle que soit la solution que vous utilisez.
    Pour ce genre de chose, autant faire du streaming directement des statistiques de calcul. Calculez une donnée une fois et interrogez-la directement lorsque vous l'utilisez.
    Afin de ne pas affecter les performances des processus normaux, les statistiques informatiques en streaming peuvent être exploitées de manière asynchrone
    Notre système a réalisé des statistiques similaires. Vous pouvez voir les 90 derniers jours en consultant les statistiques quotidiennes et les 3 dernières années. en regardant les statistiques mensuelles, auparavant, vous ne pouviez les visualiser que par année, ce qui semble être similaire à vos besoins
    J'ai écrit un petit code pour le calcul des statistiques de flux, ce qui prenait moins d'une semaine.
    github.com/panjjo/flysnow Bien sûr, l'écriture du code est assez mauvaise.

    répondre
    0
  • 高洛峰

    高洛峰2017-05-02 09:28:05

    Il s'agit d'une exigence OLAP courante dans le domaine des bases de données, et des vues matérialisées peuvent être prises en compte.

    Pour référence.

    J'adore MongoDB ! Amusez-vous!

    répondre
    0
  • 大家讲道理

    大家讲道理2017-05-02 09:28:05

    Écrire un timer résoudra le problème, c'est tout ! ! !

    répondre
    0
  • Annulerrépondre